一、设计表的原则: 1.原子性:表的字段是不可在分割的。
2.原始性:表中的数据都是最原始的(基本数据类型)
3.演绎性:由表中的数据的不同组合,可以派生出所有你想要的数据
4.稳定性:表的结构都是相对稳定的,表中的记录都是要长期保存的。
二、设计应该遵循的范式: 第一范式:确保每列数据的原子性,即不可拆分
第二范式:第一的基础上,确保每列都和主键相关(如果不相关的话,试想查询如何查询?)
第三范式:第二的基础上,确保每列都和主键直接相关(不是通过其他的列做中间引用来关联)
splite 和strip 都是python 对字符串的处理。
splite 意为分割,划分。
a='123456' a.split('3') 输出为 [‘12’, ‘456’] 可以看到,使用何种字符切割,该字符也被略去。例如这里的字符“3”
strip 意为去除,删除。
a='123456' a.strip('1') 这里可以运行下,输出’23456’ 值得注意的是,strip只能从两段开始删除,无法从中间删除。
同时不改变原字符串。这个方法,在实际使用的过程中并不多见。
一个竖杠“|”:表示运算的或;
二个竖杠“||”:表示逻辑的或;
c语言的位运算:
~取反,0取反是1,1取反是0
<<是左移,比如1<<n,表示1往左移n位,即数值大小2的n次方
>>右移,类似左移,数值大小除以2的n次方
&按位与,1与任意数等于任意数本身,0与任意数等于0,即1&x=x,0&x=0
|按位或,x|y中只要有一个1则结果为1
^按位异或,x^y相等则为0,不等则为1
c语言逻辑运算符:
&& 逻辑与,不过一旦左边的表达式为假,不进行右边表达式的运算。相当于我们的“并且”
|| 逻辑或,相当于我们日常生活中使用的“或”,也是左边的一旦为真,后面的也不判断。
!,取反,是单目运算符,将后面表达式的值取反。若后面的为真(非零),则取反后为假(0);后面的为假(0),取反后为真(1)
例:“|”和“||”的区别:
5>3|6<5
两边都计算,结果为true
5>3||6<5
只计算左边的,如果左边为true 则不计算右边的
整数在内存中是以补码的形式存放的。(符号位1表示负,0表示正) 正数的补码和源码相同;负数的补码=该数绝对值的二进制数—取反—加1; 一个有符号的int型变量(当时2个字节时)取值范围:-2∧15~(2∧15-1),既-32768~32767;无符号的int型变量的取值范围是0~65535; 若int a=32767;int b=a+1;则运行结果为b=-32768;也就是出现了溢出的情况,超过最大值后,运行时并不报错,而是从最小值开始记数。所以C语言的灵活性往往也会带来麻烦。 八进制以0开头,十六进制以0x开头; // 1、二进制数、八进制数、十六进制数转十进制数 有一个公式:二进制数、八进制数、十六进制数的各位数字分别乖以各自的基数的(N-1)次方,其和相加之和便是相应的十进制数。个位,N=1;十位,N=2...举例: 110B=1*2的2次方+1*2的1次方+0*2的0次方=0+4+2+0=6D 110Q=1*8的2次方+1*8的1次方+0*8的0次方=64+8+0=72D 110H=1*16的2次方+1*16的1次方+0*16的0次方=256+16+0=272D 2、十进制数转二进制数、八进制数、十六进制数 方法是相同的,即整数部分用除基取余的算法,小数部分用乘基取整的方法,然后将整数与小数部分拼接成一个数作为转换的最后结果。 例:见四级指导16页。 3、二进制数转换成其它数据类型 3-1二进制转八进制:从小数点位置开始,整数部分向左,小数部分向右,每三位二进制为一组用一位八进制的数字来表示,不足三位的用0补足, 就是一个相应八进制数的表示。 010110.001100B=26.14Q 八进制转二进制反之则可。 3-2二进制转十进制:见1 3-3二进制转十六进制:从小数点位置开始,整数部分向左,小数部分向右,每四位二进制为一组用一位十六进制的数字来表示, 不足四位的用0补足,就是一个相应十六进制数的表示。 00100110.00010100B=26.14H 十进制转各进制 要将十进制转为各进制的方式,只需除以各进制的权值,取得其余数,第一次的余数当个位数,第二次余数当十位数,其余依此类推,直到被除数小于权值,最后的被除数当最高位数。 一、十进制转二进制 如:55转为二进制 2|55 27――1 个位 13――1 第二位 6――1 第三位 3――0 第四位 1――1 第五位 最后被除数1为第七位,即得110111 二、十进制转八进制 如:5621转为八进制 8|5621 702 ―― 5 第一位(个位) 87 ―― 6 第二位 10 ―― 7 第三位 1 ―― 2 第四位 最后得八进制数:127658 三、十进制数十六进制 如:76521转为十六进制 16|76521 4726 ――5 第一位(个位) 295 ――6 第二位 18 ――6 第三位 1 ―― 2 第四位 最后得1276516 二进制与十六进制的关系 2进制 0000 0001 0010 0011 0100 0101 0110 0111 16进制 0 1 2 3 4 5 6 7 2进制 1000 1001 1010 1011 1100 1101 1110 1111 16进制 8 9 a(10) b(11) c(12) d(13) e(14) f(15) 可以用四位数的二进制数来代表一个16进制,如3A16 转为二进制为: 3为0011,A 为1010,合并起来为00111010。可以将最左边的0去掉得1110102 右要将二进制转为16进制,只需将二进制的位数由右向左每四位一个单位分隔,将各单位对照出16进制的值即可。 二进制与八进制间的关系 二进制 000 001 010 011 100 101 110 111 八进制 0 1 2 3 4 5 6 7 二进制与八进制的关系类似于二进制与十六进制的关系,以八进制的各数为0到7,以三位二进制数来表示。如要将51028 转为二进制,5为101,1为001,0为000,2为010,将这些数的二进制合并后为1010010000102,即是二进制的值。 若要将二进制转为八进制,将二进制的位数由右向左每三位一个单位分隔,将事单位对照出八进制的值即可 // 十进制小数转换为二进制数: (整数部分数对余数进行逆序排序,对小数部分乘积的整数进行顺序排序) 十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并。 1.
1.队列先进先出,栈先进后出。
2.对插入和删除操作的"限定"。 栈是限定只能在表的一端进行插入和删除操作的线性表。队列是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。 从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。但它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定"。 栈和队列是在程序设计中被广泛使用的两种线性数据结构,它们的特点在于基本操作的特殊性,栈必须按"后进先出"的规则进行操作,而队列必须按"先进先出"的规则进行操作。和线性表相比,它们的插入和删除操作受更多的约束和限定,故又称为限定性的线性表结构。
3.遍历数据速度不同。栈只能从头部取数据 也就最先放入的需要遍历整个栈最后才能取出来,而且在遍历数据的时候还得为数据开辟临时空间,保持数据在遍历前的一致性队列怎不同,他基于地址指针进行遍历,而且可以从头或尾部开始遍历,但不能同时遍历,无需开辟临时空间,因为在遍历的过程中不影像数据结构,速度要快的多
栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。
队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。
从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。但它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定"。
栈和队列是在程序设计中被广泛使用的两种线性数据结构,它们的特点在于基本操作的特殊性,栈必须按"后进先出"的规则进行操作,而队列必须按"先进先出"的规则进行操作。和线性表相比,它们的插入和删除操作受更多的约束和限定,故又称为限定性的线性表结构。可将线性表和栈及队列的插入和删除操作对比如下:
线性表
Insert(L,i,x)
(1≤i≤n+1)
Delete(L,i)
(1≤i≤n)
如线性表允许在表内任一位置进行插入和删除
栈
Insert(L,n+1,x)
Delete(L,n)
而栈只允许在表尾一端进行插入和删除
队列
Insert(L,n+1,x)
Delete(L,1)
队列只允许在表尾一端进行插入,在表头一端进行删除
栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。
队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。
从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。但它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定"。
单片机可以理解为集成在单一芯片上的微型计算机系统,麻雀虽小可是五脏俱全,也有运算器、控制器、存储器、总线及输入输出设备,采用也是存储程序执行的方式,对单片机的编程就是对其中的ROM写入程序,在加电后ROM中的程序会像计算机内存中的程序一样得到逐条的执行。当今的单片机还集成了A/D、D/A转换,并串口等多种与外界进行数据交换的手段。单片机计算速度和性能有限,但在一些基本控制上搓绰绰有余。 FPGA则是操控层次更低,所以自由度更大的芯片,对FPGA的编程在编译后是转化为FPGA内的连线表,相当于FPGA内提供了大量的与非门、或非门、触发器(可以用与非门形成吧)等基本数字器件,编程决定了有多少器件被使用以及它们之间的连接。只要FPGA规模够大,这些数字器件理论上能形成一切数字系统,包括单片机甚至CPU。FPGA在抗干扰,速度上有很大优势。 单片机和FPGA的区别,本质是软件和硬件的区别。 单片机设计属软件范畴;它的硬件(单片机芯片)是固定的,通过软件编程语言描述软件指令在硬件芯片上的执行; FPGA设计属硬件范畴,它的硬件(FPGA)是可编程的,是一个通过硬件描述语言在FPGA芯片上自定义集成电路的过程; 主要是结构上的区别 单片机是一种微处理器,类似于电脑CPU的,它一般采用的是哈佛总线结构,或者冯诺依曼结构,对单片机的编程很大程度上要考虑到它的结构和各个寄存器的作用,单片机用途比较广,一般用在控制流水线上,还有日 常你看得到的东西上! FPGA 它的结构是查找表结构,其程序不用去太考虑芯片的结构,要注意的是时序上问题,它的结构比较复杂,功能也很强大,一般应用在通信领域等比较高端的场合,目前在国内FPGA还算是一个新兴的行业,当然它的价格也要比单片机贵得多! 二者最大的区别:单片机(无论哈佛总线结构或者冯诺依曼结构)均为取出指令->执行,指令是顺序执行的(即使是中断,其发生后的中断服务程序也是顺序执行的);而FPGA(包括CPLD)是基于逻辑门和触发器的,它是并行执行方式,即当CLOCK上升沿到来时,所有的触发器都会动作,它没有取出指令->执行这种操作,数字电路中所有逻辑门和触发器(D,SR等)均可以实现,它适合真正意义上的并行任务处理。
要将 ASP.NET 访问权限授予某个文件,请在资源管理器中右击该文件,选择“属性”,然后选择“安全”选项卡。单击“添加”添加适当的用户或组。突出显示 ASP.NET 帐户,选中所需访问权限对应的框。 找到该文件所在文件夹,右键属性,安全选项卡,添加-aspnet用户,并设置其权限为完全控制。如果还是不行,就添加一个Everyone用户并赋予完全控制权限
windows server 2008中IIS中windows身份验证开启ASP.NET模拟身份验证 转载于:https://www.cnblogs.com/qianxingdewoniu/p/7092908.html
利用re模块提取字符串中的数字 [0-9]* 是数字匹配的正则表达式
findlist = re.findall('(\w*[0-9]+)\w*', emp_length_val)
# coding: utf-8 # # 数据连接 merge # In[1]: import pandas as pd import numpy as np # In[3]: df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1' : np.random.randint(0,10,7)}) df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'], 'data2' : np.random.randint(0,10,3)}) print(df_obj1) print(df_obj2) # In[4]: # 默认将重叠列的列名作为“外键”进行连接 pd.merge(df_obj1, df_obj2) # In[5]: # on显示指定“外键” pd.merge(df_obj1, df_obj2, on='key') # In[6]: # left_on,right_on分别指定左侧数据和右侧数据的“外键” # 更改列名 df_obj1 = df_obj1.rename(columns={'key':'key1'}) df_obj2 = df_obj2.rename(columns={'key':'key2'}) # In[7]: pd.
出现这种情况是把时间直接按String读取相当于先取java.sql.Timestamp该类型数据然后再对该数据进行toString()的结果。 对这种数据处理的方法,这里提供两种一种在后台处理,一种在前台处理 后台处理方法: 由于每条数据都是以.0结尾,因此我们可以对其进行截取字符串的方式处理。
String date = “2017-06-02 15:39:22.0”; String newDate = date.substring(date.length-2,date.length); 前台处理方法: 对获取的时间进行格式化处理:
<fmt:formatDate value="${date}" type="both" pattern="yyyy-MM-dd HH:mm:ss"/>
原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被中断的一个或一系列操作”。在多处理器上实现原子操作就变得有点复杂。让我们一起来聊一聊在Intel处理器和Java里是如何实现原子操作的。
1.术语定义
在了解原子操作的实现原理前,先要了解一下相关的术语,如表2-7所示。
2.处理器如何实现原子操作
32位IA-32处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作。首先处理器会自动保证基本的内存操作的原子性。处理器保证从系统内存中读取或者写入一个字节是原子的,意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址。Pentium 6和最新的处理器能自动保证单处理器对同一个缓存行里进行16/32/64位的操作是原子的,但是复杂的内存操作处理器是不能自动保证其原子性的,比如跨总线宽度、跨多个缓存行和跨页表的访问。但是,处理器提供总线锁定和缓存锁定两个机制来保证复杂内存操作的原子性。
(1)使用总线锁保证原子性
第一个机制是通过总线锁保证原子性。如果多个处理器同时对共享变量进行读改写操作(i++就是经典的读改写操作),那么共享变量就会被多个处理器同时进行操作,这样读改写操作就不是原子的,操作完之后共享变量的值会和期望的不一致。举个例子,如果i=1,我们进行两次i++操作,我们期望的结果是3,但是有可能结果是2,如图2-3所示。
原因可能是多个处理器同时从各自的缓存中读取变量i,分别进行加1操作,然后分别写入系统内存中。那么,想要保证读改写共享变量的操作是原子的,就必须保证CPU1读改写共享变量的时候,CPU2不能操作缓存了该共享变量内存地址的缓存。
处理器使用总线锁就是来解决这个问题的。所谓总线锁就是使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞住,那么该
处理器可以独占共享内存。
(2)使用缓存锁保证原子性
第二个机制是通过缓存锁定来保证原子性。在同一时刻,我们只需保证对某个内存地址的操作是原子性即可,但总线锁定把CPU和内存之间的通信锁住了,这使得锁定期间,其他处理器不能操作其他内存地址的数据,所以总线锁定的开销比较大,目前处理器在某些场合下使用缓存锁定代替总线锁定来进行优化。
频繁使用的内存会缓存在处理器的L1、L2和L3高速缓存里,那么原子操作就可以直接在处理器内部缓存中进行,并不需要声明总线锁,在Pentium 6和目前的处理器中可以使用“缓存锁定”的方式来实现复杂的原子性。所谓“缓存锁定”是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不在总线上声言LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改由两个以上处理器缓存的内存区域数据,当其他处理器回写已被锁定的缓存行的数据时,会使缓存行无效,在如图2-3所示的例子中,当CPU1修改缓存行中的i时使用了缓存锁定,那么CPU2就不能同时缓存i的缓存行。
但是有两种情况下处理器不会使用缓存锁定。
第一种情况是:当操作的数据不能被缓存在处理器内部,或操作的数据跨多个缓存行(cache line)时,则处理器会调用总线锁定。
第二种情况是:有些处理器不支持缓存锁定。对于Intel 486和Pentium处理器,就算锁定的内存区域在处理器的缓存行中也会调用总线锁定。
针对以上两个机制,我们通过Intel处理器提供了很多Lock前缀的指令来实现。例如,位测试和修改指令:BTS、BTR、BTC;交换指令XADD、CMPXCHG,以及其他一些操作数和逻辑指令(如ADD、OR)等,被这些指令操作的内存区域就会加锁,导致其他处理器不能同时访问它。
3.Java如何实现原子操作
在Java中可以通过锁和循环CAS的方式来实现原子操作。
(1)使用循环CAS实现原子操作
JVM中的CAS操作正是利用了处理器提供的CMPXCHG指令实现的。自旋CAS实现的基本思路就是循环进行CAS操作直到成功为止,以下代码实现了一个基于CAS线程安全的计数器方法safeCount和一个非线程安全的计数器count。
/** * Alipay.com Inc. * Copyright (c) 2004-2015 All Rights Reserved. */ package chapter02; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * 计数器 * * @author tengfei.fangtf * @version $Id: Snippet.java, v 0.1 2015-7-31 下午11:32:42 tengfei.fangtf Exp $ */ public class Counter { private AtomicInteger atomicI = new AtomicInteger(0); private int i = 0; public static void main(String[] args) { final Counter cas = new Counter(); List<Thread> ts = new ArrayList<Thread>(600); long start = System.
1、 背景介绍 在板上,ZYNQ PL部分通过EMC连接一片NOR FLASH,地址空间如下:
可以看到NOR FLASH的起始地址为0x80000000,这是物理地址,可以把数据存放在以该地址起始的一段区域。
需要注意的是,在对NOR FLASH进行读写数据时,需要参考对应的datasheet,例如这里选用的NOR FLASH读、写、擦除步骤如下:
通过上面的表格就知道进行相应操作每一步该做什么,可以转换为SDK中裸奔程序的C代码。
2、 Linux下flash操作 之前提到过zynq中Linux用户应用程序可以通过/dev/mem访问到物理地址,xil_in32和xil_out32等裸奔程序中常见的函数可以通过这一机制移植到linux下。于是,对flash的操作其实就是基于xil_in和xil_out对物理地址进行读写。
这里只需要实现三个函数,erase,write_sector以及read_sector.代码如下:
//xil_io.h #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> #define PAGE_SIZE ((size_t)getpagesize()) #define PAGE_MASK ((uint64_t) (long)~(PAGE_SIZE - 1)) void Xil_Out32(uint64_t phyaddr, uint32_t val) { int fd; volatile uint8_t *map_base; uint64_t base = phyaddr & PAGE_MASK; uint64_t pgoffset = phyaddr & (~PAGE_MASK); if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { perror("
1、事务未提交 在使用spring test 做单元测试时,debug导致事务没有提交,Lock wait timeout exceeded; 定位到该表,直接navicat 上insert 该表,Lock wait timeout exceeded; 确认是该表的事务没有提交,锁被占用没释放: select * from information_schema.innodb_trx; 查看到堵塞的线程,kill trx_mysql_thread_id, 2、表级锁被阻塞 同事在查询数据库数据写入到excel时,数据量较大有200万,未能正确分页,导致数据库锁等待卡死; show processList; 查看到多个线程处于sending data的状态, kill掉 线程,恢复数据库; 并将存储引擎由MyIsam 改为 INnnoDB,可减少表级锁。
前言 在jdk的源码中,用到大量的从源数组考贝到目标数组的操作,既然涉及到数组,那会一定会有数组的越界检查问题。今天就列举出一个,基本思想要掌握
源码 ByteArrayOutputStream中的一个方法
public synchronized void write(byte b[], int off, int len) { if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0)) { throw new IndexOutOfBoundsException(); } ... } off指的是从源数组的哪个索引开始 则off < 0 或 off > b.length 发生越界 len则是考贝的长度 则len < 0 或 off + len > b.length 也是错误的
对源码提出的疑问 当off = b.length时,也会发生越界问题,为什么没有加以判断呢? 是有意为之,还是个bug呢?
寥寥数笔,记录我的C语言盲点笔记,只为曾经经历过,亦有误,可交流。
1.typedef来定义一个函数指针类型的方法,定义一个新的函数指针类型。 :建立一个类型别名的方法很简单,在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头”。
typedef int (*PFUN)(): 定义PFUN这个函数指针类型,由编译器自动来完成,比如PFUN pfun;定义了一个函数指针,类似于抽象出一种新的变量类型。
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
pTaskEventHandlerFn tasksArr[];//申明函数指针的数组
使用typedef将一个类型名字替代原先申明时的变量名,然后类型名可以用来申明定义变量。
2.有初始化的数组定义可以省略方括号中的数组大小。
例如,下面的代码中数组定义为5个元素:
int a[]={2,4,6,8,10};
编译时必须知道数组的大小。通常,声明数组时方括号内的数字决定了数组的大小。有初始化的数组定义又省略方括号中的数组大小时,编译器统计花括号之间的元素个数,以求出数组的大小。
例如,下面的代码产生相同的结果:
static int a1[5]={1,2,3,4,5};
static int a2[]={1,2,3,4,5};
2,栈顶一般为低地址,函数入栈一般参数从右往左进行。
3.for(a;b;c){e}执行顺序:
先进行a, 然后是b, 执行e, 在执行c.进一步执行b,执行e,c.直到b不再满足退出循环。
4.union数据类型,内存是重叠的,完全一样
typedef union {
uint32 time32;
uint16 time16[2];
uint8 time8[4];
} osalTime_t;
对time32的赋值后,访问其他类型时依旧是原来的内存。三个成员占据一样的数据空间,起始地址都是一样的,一旦一个成员数值变化就会出现其他成员取值也发生变化
5.inline内联函数总结
内联函数具有代码量小且直接编译进可执行文件中,不进行call调用,也就是在不同的文件的函数如果调用内联函数,则不同的函数都会出现该内联函数的可执行代码。
但是,如果不重复调用的话,内联函数带来的好处就是执行更加快速,无需再call,以及函数参数的出入栈SP,保护栈帧,跳出函数,清空栈帧等各种耗时。起到快速执行的效果。故内联函数的代码量都较小。
总之是以增加执行文件大小来获取程序执行速度的提高。
6.(int *)0,表示指向一个整形的地址,地址值为0,即空指针所在的地方,该处一般不允许写操作,以免破坏系统,但可以读取。
7.如果一个函数要被其他文件中函数使用,定义时加extern关键字,在没有加extern和static关键字时,一般编译器会默认是extern类型的,因此你在其他函数里调用也可以使用。
8.结构体之offsetof宏详细解析 ,#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) (include/linux/stddef.h)
9.32位机读取一个字节,实际底层的汇编做了进一步的处理。
比如读取一个字节,实际返回的是一个32位,经过屏蔽移位取得你要的地址所在的数。写入时也一样,会先保持4字节其他字节不变,然后单独把要写入的字节做改变。由编译器根据你的数据类型来完成实际的实现。
原文转载于:http://blog.csdn.net/shichaog/article/details/52514816 非常感谢。
WebRTC噪声抑制核心算法在ns_core.c文件里。
噪声频谱可以使用如语音/噪声似然函数进行估计。将接收到的每帧信号和频率分量分类为噪声或语音。
算法原理
该算法的核心思想是采用维纳滤波器抑制估计出来的噪声。
上式中x和n分别表示语音和噪声,而y表示麦克风采集到的信号。
它们的频谱关系如上,从上图可以看出语音和噪声是加性且不相关的关系,对于非加性关系可以有AEC等算法对不同场景进行抑制。根据中心极限定义,一般认为噪声和语音分布服从均值为0,方差为ui的正态分布。但是也有采用和分布的情况。
所以这里的中心思想就变成了从Y中估计噪声N,然后抑制N以得到语音,即:
所以对噪声的估计准确性是至关重要的,噪声估计的越准得到的结果就越好,由此又多出来几种估计噪声的方法。
1. 基于VAD检测的噪声估计,VAD对Y进行检测,如果检测没有语音,则认为噪声,这是对噪声的一种估计方法。
2.基于全局幅度谱最小原理,该估计认为幅度谱最小的情况必然对应没有语音的时候。
3.还有基于矩阵奇异值分解原理估计噪声的。
webRTC没有采用上述的方法,而是对似然比(VAD检测时就用了该方法)函数进行改进,将多个语音/噪声分类特征合并到一个模型中形成一个多特征综合概率密度函数,对输入的每帧频谱进行分析。其可以有效抑制风扇/办公设备等噪声。
其抑制过程如下:
对接收到的每一帧带噪语音信号,以对该帧的初始噪声估计为前提,定义语音概率函数,测量每一帧带噪信号的分类特征,使用测量出来的分类特征,计算每一帧基于多特征的语音概率,在对计算出的语音概率进行动态因子(信号分类特征和阈值参数)加权,根据计算出的每帧基于特征的语音概率,修改多帧中每一帧的语音概率函数,以及使用修改后每帧语音概率函数,更新每帧中的初始噪声(连续多帧中每一帧的分位数噪声)估计。
基于特征的语音概率函数通过使用映射函数(sigmoid/tanh又称S函数,在神经元分类算法中常用为种子函数)将每帧的信号分类特征映射到一个概率值而得出的。
分类特征包括:随时间变化的平局似然比,频谱平坦度测量以及频谱模板差异测量。频谱模板差异测量以输入信号频谱与模板噪声频谱的对比为基础。
信号分析:包括缓冲、加窗和离散傅立叶变换(DFT) 的预处理步骤
噪声估计和过滤包括:初始噪声估计、后验和先验SNR的判决引导(DD)更新、语音/噪声可能性测定,可能性测定是基于似然比(LR)因子进行的,而似然比是使用后验和先验SNR,以及语音概率密度函数(HF)模型 (如高斯、拉普拉斯算子、伽马、超高斯等),还有根据特征建模、噪声估计更新并应用维纳增益滤波器确定的概率而确定的。
信号合成:离散傅立叶逆变换、缩放和窗口合成。
初始噪声估计是以分位数噪声估计为基础。噪声估计受分位数参数控制,该参数以q表示。根据初始噪声估计步骤确定的噪声估计,仅能用作促进噪声更新/估计的后续流程的初始条件。
set_feature_extraction_parameters 设置了特征提取使用到的参数,当前WebRTC噪声抑制算法使用了LRT特征/频谱平坦度和频谱差异度三个指标,没有使用频谱熵和频谱方差这两个特征。
WebRtc Ns_Init Core NS(noise suppression)模块初始化,后面的代码按fs=8000,来分析。
[cpp] view plain copy //语音数据的长度,8k/10ms的数据量是80 self->blockLen = 80; //分析长度,由于是在频域分析,将长度像上取2的幂次,最小的值是128,实际上是fft的长度。 self->anaLen = 128; //窗函数,采用混合汉宁平顶窗函数 self->window = kBlocks80w128; 初始化FFT用到的相关存储成员 [cpp] view plain copy // Initialize FFT work arrays. self->ip[0] = 0; // Setting this triggers initialization. memset(self->dataBuf, 0, sizeof(float) * ANAL_BLOCKL_MAX); WebRtc_rdft(self->anaLen, 1, self->dataBuf, self->ip, self->wfft); //是滑动分析窗,针对80点128的fft而言,每一次会保留前一帧的128-80=48个点的数据,而不是对80点简单填充0变成128点做fft。 //但这会带来合成上的问题,通常采用加窗以防止重叠带来的突变。可以使用做fft变换一样的窗函数。但这要求窗函数保幂映射,即重叠 //区部分窗口的平方和必须为1.
如何利用单片机的ADC模块(或者独立的ADC芯片)得到接入ADC管脚上的实际电压值? 这个问题,是第一次接触ADC时候,大家都会遇到的问题。 会读到什么值 单片机会读到什么值?需要看一个特性,就是几位的ADC,在手册上就会给出,例如,STM32的ADC是12位的。另外,还有8位,10位,16位,24位等。 我先告诉你答案:STM32读到的ADC值,是从0到4095,当你把ADC引脚接了GND,读到的就是0,当你把ADC引脚接了VDD,读到的就是4095。 接下来告诉你为什么:前面提到,STM32的ADC是12位的,我们知道,8位的值是从0~255;16位的值,是从0~65535。这两个位的最大值,是我们最为熟悉的。 (怎么算出来的?这问题就又降低到另一个层面了,这里我们说的几位的值,每个位只能是0或者1,比如2位的值,可以表示为00 01 10 11四种不同的值,这是以2进制表示的,转换成十进制就是0 1 2 3,所以得出结论,2位的值可以表示从0~3。同理,3位的值,可以表示十进制的0~9,你可以展开计算一下。4位的值,可以表示0~16,5位的值,可以表示从0~31,同理,你可以得出任意位的值可以表示的范围。) 所以,12位的值,可以表示从0~4095,这就是先在感性上,认识了为什么12位的ADC的值,是从0~4095. 读到的值怎么换算成实际的电压值 前面提到了,我们输入GND,读到的值是0,输入VDD,得到的值是4095,那么,当你读到2035的时候,你知道输入电压多少V吗?这个问题,归根接地,就到了数学XY坐标,已知两点坐标值(0,0)(3.3,4095),给出任意X坐标值,求Y值的问题了吧?简单不简单? 参考电压是什么 讨论这个问题之前,你先拿万用表量一下你的VDDA的实际电压是多大?是不是标准的3.300V?应该不是吧?或许是2.296V,或许是3.312V。然后你把VDD连接到ADC引脚之后,得到的是4095,也就是,实际上,当你读出4095这个数据的时候,实际的电压值不是你想象中的3.300V。有些初学者,觉得几毫伏的电压差无所谓,但实际应用中,几毫伏就可能代表很大的实际工况,例如,在一个量程为50克的电子称上。 所以,这时候,芯片厂商就想了一个办法,给ADC模块中引入参考电压,由非常标准的参考电压芯片来接入参考电压引脚。标准的电压芯片,我们一般叫做参考电压芯片,或者叫做基准电压芯片。例如REF3133(输出3.300V) REF3025(输出2.500V)等等。 注意:STM32 的100脚以上(含100脚)有参考电压引脚。在没有参考电压引脚的单片机上,可以把基准电压芯片接入VDDA,但是VDDA和VDD的电压差不能超过0.3V,例如,VDD是3.3V的话,可以给VDDA接入一个3.3V的参考电压芯片或者3.0V的参考电压芯片,但是不能接入2.5V的参考电压芯片,后果就是芯片不能工作。 ADC引脚的输入电压范围是多大 一般情况下,ADC引脚的输入电压,是从0~VDD,如果有REF引脚,一般是0~Vref,也有0~2Vref的情况。 如果被测的电压大于ADC的输入电压,例如,要用STM32测量0~5V的电压的话,可以在输入ADC引脚之前,加入电阻分压和放大器电路。 总结:看完这篇文章,你是否会觉的,一切都只是基础知识的融合
简介 awk 是一种对立的编程语言,集成于所有UNIX/Linux中,这个名字是它创建者的名字首字母组成的 Alfred Aho,Peter Weinberger, and Brian Kernighan。
awk的基本语法 普通模式 awk '/pattern/{action}' files 其中patter是一个正则表达式,action又是一系列命令,对于满足匹配的文本执行一些动作,files表示待操作的文件,如果不指定,则输入是STDIN。如果不指定pattern,则对所有文件的每一行都执行action。
表达式模式 当在awk中使用比较操作符时,使用下面的语法模式,详见后面。
awk '(expression){action}' files 有如下一个示例文件
zdd.txt包含如下内容
Fruit Price/lbs Banana 0.89 Paech 0.79 Kiwi 1.50 Pineapple 1.29 Apple 0.99 显示一个文件的所有行 awk '{ print ; }' zdd.txt 分号表示命令结束,这个例子没有pattern,只有action
域编辑 awk自动将读入的行分割成域(field),域是由一个或多个分隔符分割开的字符集,缺省的分隔符是tab和空格,访问域可以用$1,$2, ... $n的形式,域都是从1开始的,而$0表示整个行(以行本来的面目呈现)
格式化输出水果及价格
awk '{ printf "%-15s %s\n", $1, $2 ;}' zdd.txt 输出如下
Fruit Price/lbs Banana 0.89 Paech 0.79 Kiwi 1.50 Pineapple 1.29 Apple 0.99 使用其他的域分隔符 awk的-F参数可以制定其他的域分隔符,比如下面的代码将打印D
1. 权限:
google play会对那些app里使用了相关硬件权限的情况做处理(比如: Android.permission.CAMERA), 某些设备就不能直接从google play
下载app(比如: Nexus 7),表象就如图所示提示"Your device isn't compatible with this version"。
对于此种情况,告诉google play,我这个权限并非必须使用即可。
[java] view plain copy <uses-permission android:name="android.permission.CAMERA" /> <!-- 解决某些设备不能从google play下载app的问题,声明此硬件使用并非必要--> <uses-feature android:name="android.hardware.camera" android:required="false"/> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> 2.设置国家:
建议设置所有国家
不积跬步,无以至千里
说起我为什么要写这篇文章?就是因为我入坑了,所以我写下这篇来提醒有可能也入坑的人(废了2天时间啊)!
先说下AlarmManager的使用吧(我这里使用的AlarmManager的repeating方法),再说说入坑的事。 首先我先把最终要用的方法贴到这里,再让你们看下接下来的其中方法中参数等的由来。
一、设置闹钟
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, AlarmManager.INTERVAL_DAY, uploadIntent); 1、先获取到AlarmManager对象
AlarmManager alarmManager = (AlarmManager) context.getSystemService( Context.ALARM_SERVICE); 2、获取到PendingIntent的意图对象,即方法中的最后一个参数(你打算用这个intent去干什么,开启服务还是发送广播,打开Activity等等) Intent intent2 = new Intent(context, LauncherService.class).setAction(Constants.PENDING_START_ALARM_ACTION+""); PendingIntent uploadIntent = PendingIntent.getService(context, 0, intent2, PendingIntent.FLAG_UPDATE_CURRENT); 3、获取使用repeating方法时,需要填入的第二个参数,即你第一次触发这个重复闹钟的时间,其中注意的是,因为我下面seRepeating方法第一个参数ELAPSED_REALTIME ,所以我在获取时间的时候是用systemTime = System.elapsedRealtime()其中这个包括了手机系统的睡眠时间,现对于比较准确。AlarmManager的方法时注意中一些参数的上下的一致性。否则会出现定时的错误!
long firstTime = SystemClock.elapsedRealtime();//boot from begin to now runnig time ,it includes sleep time long systemTime = System.currentTimeMillis(); Calendar calendar = Calendar.getInstance(); //calendar.setTimeInMillis(systemTime); //setting the TimeZone,or else will have the time mistakes(8 hours) // calendar.setTimeZone(TimeZone.getTimeZone("GMT+8")); calendar.
在使用mysql时,有时需要查询出某个字段不重复的记录,这时可以使用mysql提供的distinct这个关键字来过滤重复的记录,但是实际中我们往往用distinct来返回不重复字段的条件(count(distinct id)),其原因是distinct只能返回他的目标字段,而无法返回其他字段,例如有如下表user: 用distinct来返回不重复的用户名select distinct name from user,结果为: 这样只把不重复的用户名查询出来了,但是用户的id,并没有被查询出来,如果想要查询不重复的id和name:select distinct name, id from user 像select distinct name, id from user这样的mysql会把name, id字段都重复的记录过滤掉。
但是sql这样写:select id, distinct name from user,这样mysql会报错 因为distinct必须放在要查询字段的开头。 所以一般distinct用来查询不重复记录的条数。 如果要查询不重复的记录,有时候可以用group by:
select id, name from user group by name 参考文献 mysql中去重 distinct 用法:http://blog.csdn.net/xiaofan1988/article/details/43564133
例如,$ 表示当前Shell进程的ID,即pid,看下面的代码: $echo $$ 运行结果 29949 特殊变量列表 变量含义$0当前脚本的文件名$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。$#传递给脚本或函数的参数个数。$*传递给脚本或函数的所有参数。$@传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。$?上个命令的退出状态,或函数的返回值。$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 命令行参数 运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。 请看下面的脚本: #!/bin/bash echo "File Name: $0"echo "First Parameter : $1"echo "First Parameter : $2"echo "Quoted Values: $@"echo "Quoted Values: $*"echo "Total Number of Parameters : $#" 运行结果: $./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2 $* 和 $@ 的区别 $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号("
引用:
http://www.51testing.com/?uid-7701-action-viewspace-itemid-13731
http://blog.csdn.net/sunboy_2050/article/details/6836382
shell 括号
学习shell的时候总是被shell里的条件判断方式搞得头疼,经常不知道改 用[],[[]],(())还是test,let,而很少有书把它们的关系讲解的很清楚(应该是我悟性差或是看书太少),今天总结一下,基础的东西如它们 的使用方法不再赘述,重点说说它们的区别的使用时应该注意的地方。
先说[]和test,两者是一样的,在命令行里test expr和[ expr ]的效果相同。test的三个基本作用是判断文件、判断字符串、判断整数。支持使用与或非将表达式连接起来。要注意的有:
1.test中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq, -gt这种形式。无论是字符串比较还是整数比较都千万不要使用大于号小于号。当然,如果你实在想用也是可以的,对于字符串比较可以使用尖括号的转义形式, 如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0.
然后是[[ ]],这是内置在shell中的一个命令,它就比刚才说的test强大的多了。支持字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达 式)。简直强大的令人发指!逻辑组合可以不使用test的-a,-o而使用&&,||这样更亲切的形式(针对c、Java程序员)。当 然,也不用想的太复杂,基本只要记住
1.字符串比较时可以把右边的作为一个模式(这是右边的字符串不加双引号的情况下。如果右边的字符串加了双引号,则认为是一个文本字符串。),而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。
另外要注意的是,使用[]和[[]]的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]的结果为“假”,但[[ 1==2 ]]的结果为“真”!后一种显然是错的
3.最后就是let和(()),两者也是一样的(或者说基本上是一样的,双括号比let稍弱一些)。主要进行算术运算(上面的两个都不行),也比较适合进 行整数比较,可以直接使用熟悉的<,>等比较运算符。可以直接使用变量名如var而不需要$var这样的形式。支持分号隔开的多个表达式
####################################################################################################################################
1. 首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
"[[",是关键字,许多shell(如ash bsh)并不支持这种方式。ksh, bash(据说从2.02起引入对[[的支持)等支持。
"["是一条命令, 与test等价,大多数shell都支持。在现代的大多数sh实现中,"["与"test"是内部(builtin)命令,换句话说执行"test"/"["时不会调用/some/path/to/test这样的外部命令(如果有这样的命令的话)。
2.[[]]结构比Bash版本的[]更通用。在[[和]]之间的所有的字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。
用[[ ... ]]测试结构比用[ ... ]更能防止脚本里的许多逻辑错误。比如说,&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构会发生错误。
3.(( ))结构扩展并计算一个算术表达式的值。如果表达式值为0,会返回1或假作为退出状态码。一个非零值的表达式返回一个0或真作为退出状态码。这个结构和先前test命令及[]结构的讨论刚好相反。
4.[ ... ]为shell命令,所以在其中的表达式应是它的命令行参数,所以串比较操作符">" 与"<"必须转义,否则就变成IO改向操作符了(请参看上面2中的例子)。在[[中"<"与">"不需转义;
由于"[["是关键字,不会做命令行扩展,因而相对的语法就稍严格些。例如
在[ ... ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ ... ]]则不允许这样做。
5.[[ ... ]]进行算术扩展,而[ ... ]不做
6.[[ .
吐槽一下,坑太多。
闪开,老司机开车了。
系统环境:win10 64位,Python3.5。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1、下载源码
https://github.com/tzutalin/labelImg, download之后,解压。
2、安装Python3.5
不要用3.6!不要用3.6!不要用3.6!到目前为止,当执行" from lxml import etree "时,会失败,目前没有解决办法。
这里推荐一篇文章, Windows10下python3和python2同时安装, 3、安装PyQt5
进入cmd后,输入: pip install PyQt5 此处有坑,基本上这条命令执行后,因网络问题会出现执行不成功的情况,如下图
怎么办?手动下载whl文件。
注意这里的pip,一定要是Python3.5版本的,如果pip有问题,安装上述第二步重新安装Python3.5。
这里有个技巧,执行pip命令之后,它会自动寻找最合适(匹配你的系统、Python版本)的whl文件,文件名就是Downloading 之后的名字,即 PyQt5-5.8.2-5.8.0-cp35.cp36.cp37-none-win_amd64.whl, 百度下载这个文件就可以,链接直在这, https://pypi.python.org/pypi/PyQt5/5.8.2
下载后直接安装, 输入命令 :pip install XXX.whl, 如下图:
4、安装PyQt5_tools
同上,执行命令: pip install pyqt5-tools, 如下图,同样会网络原因安装失败,
得到文件名称pyqt5_tools-5.8.2.1.0rc2-cp35-none-win_amd64.whl, 百度下载,链接 https://pypi.python.org/pypi/pyqt5-tools, 下载后直接安装, 命令 :pip install XXX.whl, 如下图:
5、安装lxml
命令:pip install lxml, 如下图:
由于lxml文件很小,一般可以安装成功,不行的话,同上述方法,下载whl文件再pip安装。
6、pyrcc编译资源文件
进入到labelImg解压后的文件,我这里是labelImg-master.
执行命令: pyrcc5 -o resources.py resources.qrc , 如下图
这是个转换命令,把Qt文件格式转为Python格式。
7、打开labelImg.py
两种方法,方法1,直接在命令窗口中,输入 python3 labelImg.
一。 简单介绍keepalived
keepalived提供基于linux高可用性负载均衡技术,基于VRRP协议(虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP))主要 用于主从结构提供服务 主从机器 必须安装keepalived 主机器 会默认给主机设置一个虚拟ip 同时将该虚拟ip和主机器的mac地址路由出去,当主机挂掉后 从机检测到主机不可达(互相发送心跳) 将虚拟ip收回 将虚拟ip和从机mac地址路由出去 其他机器访问的就是从机
keepalive配置解释
默认的配置文件位于 /etc/keepalived/keepalived.conf目录下
keepalive 提供了vip转移 lvs健康检查 自定义健康检查等功能
常用配置文件解释
#全局配置 global_defs { #出现机器挂掉通知邮件配置 可以配置多个邮件地址 notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } #从哪个邮箱发出 notification_email_from Alexandre.Cassen@firewall.loc #smtp服务器 smtp_server 192.168.200.1 #smtp连接超时时间 smtp_connect_timeout 30 #路由编号 每台机器不一样 发送邮件 使用这个表示表示当前主机挂了 router_id LVS_DEVEL } #定义检测服务是否停止的脚本 该脚本只要返回任何非0的数字和字符串表示服务器存活 返回0表示服务器挂了 vrrp_script chk_cur_tomcat { #自己编写该脚本 注意脚本返回0表示挂了 script "/etc/keepalived/mytomcat_check.sh" #调用该脚本的检测时间 每 2s检查一次 interval 2 #当通过调用脚本检测失败后 vrrp_instance 配置的priority会减掉该weight 新的priority=priority-weight=95 再次失败继续减少 weight -5 #失败3次 才算失败 重连3次 fall 3 #成功两次 才算成功 rise 2 } #配置当前ip映射到虚拟ip vrrp_instance tomcat135 { #表示主从部分的主机 是个表示 对应的是BACKUP state MASTER #虚拟ip绑定的网卡名称 interface eth0 #eth0的物理ip mcast_src_ip 192.
window.onload = function () { var canvas = document.getElementById('hwsy_ypt_canvas'); var video = document.getElementById('hwsy_ypt_video'); var context = canvas.getContext("2d"); canvas.width = screen.width; canvas.height= screen.height; //------------------------- var AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext; AudioContext = new AudioContext(); var fen = AudioContext.createAnalyser(); var src = AudioContext.createMediaElementSource(video); src.connect(fen); fen.connect(AudioContext.destination); //------------------------- amoe(); video.play(); function amoe() { context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight); var Data = new Uint8Array(fen.frequencyBinCount); fen.getByteFrequencyData(Data); // Data 就是动画执行时的音频代码 1024个数组成 context.fillStyle = "#FFF"; context.font = "
一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误,比如: error while loading shared libraries: libprotobuf.so.9: cannot open shared object file: No such file or directory
原因一般有两个,一个是操作系统里确实没有包含该共享库(lib*.so.*文件)或者共享库版本不对,遇到这种情况那就去网上下载并安装上即可。
另外一个原因就是已经安装了该共享库,但执行需要调用该共享库的程序的时候,程序按照默认共享库路径找不到该共享库文件。 如上图,编译、执行protobuf示例代码时报该错,但在目录/usr/local/lib下我们可以看到libprotobuf.so.9是存在的:
所以安装共享库后要注意共享库路径设置问题,如下:
1)如果共享库文件安装到了/lib或/usr/lib目录下, 那么需执行一下ldconfig命令。
ldconfig命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的链接和缓存文件。缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。
2)如果共享库文件安装到了/usr/local/lib(很多开源的共享库都会安装到该目录下)或其它“非/lib或/usr/lib”目录下,那么在执行ldconfig命令前,还要把新共享库目录加入到共享库配置文件/etc/ld.so.conf中,如下:
# cat /etc/ld.so.conf include ld.so.conf.d/*.conf # echo "/usr/local/lib" >> /etc/ld.so.conf # ldconfig 3)如果共享库文件安装到了其它“非/lib或/usr/lib”目录下, 但是又不想在/etc/ld.so.conf中加路径(或者是没有权限加路径)。那么可以export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找共享库。
LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库。可以设置多个搜索目录,这些目录之间用冒号分隔开。比如安装了一个mysql到/usr/local/mysql目录下,其中有一大堆库文件在/usr/local/mysql/lib下面,则可以在.bashrc或.bash_profile或shell里加入以下语句:
export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH 一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
转自 http://blog.csdn.net/sahusoft/article/details/7388617
本文由 ImportNew - lemeilleur 翻译自 javarevisited。欢迎加入 翻译小组。转载请见文末要求。 Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动。特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里。在Java 8之前,如果想将行为传入函数,仅有的选择就是匿名类,需要6行代码。而定义行为最重要的那行代码,却混在中间不够突出。Lambda表达式取代了匿名类,取消了模板,允许用函数式风格编写代码。这样有时可读性更好,表达更清晰。在Java生态系统中,函数式表达与对面向对象的全面支持是个激动人心的进步。将进一步促进并行第三方库的发展,充分利用多核CPU。尽管业界需要时间来消化Java 8,但我认为任何严谨的Java开发者都不应忽视此次Java发布的核心特性,即lambda表达式、函数式接口、流API、默认方法和新的Date以及Time API。作为开发人员,我发现学习和掌握lambda表达式的最佳方法就是勇于尝试,尽可能多练习lambda表达式例子。鉴于受Java 8发布的影响最大的是Java集合框架(Java Collections framework),所以最好练习流API和lambda表达式,用于对列表(Lists)和集合(Collections)数据进行提取、过滤和排序。我一直在进行关于Java 8的写作,过去也曾分享过一些资源来帮助大家掌握Java 8。本文分享在代码中最有用的10个lambda表达式的使用方法,这些例子都短小精悍,将帮助你快速学会lambda表达式。
Java 8 lambda表达式示例 我个人对Java 8发布非常激动,尤其是lambda表达式和流API。越来越多的了解它们,我能写出更干净的代码。虽然一开始并不是这样。第一次看到用lambda表达式写出来的Java代码时,我对这种神秘的语法感到非常失望,认为它们把Java搞得不可读,但我错了。花了一天时间做了一些lambda表达式和流API示例的练习后,我开心的看到了更清晰的Java代码。这有点像学习泛型,第一次见的时候我很讨厌它。我甚至继续使用老版Java 1.4来处理集合,直到有一天,朋友跟我介绍了使用泛型的好处(才意识到它的好处)。所以基本立场就是,不要畏惧lambda表达式以及方法引用的神秘语法,做几次练习,从集合类中提取、过滤数据之后,你就会喜欢上它。下面让我们开启学习Java 8 lambda表达式的学习之旅吧,首先从简单例子开始。
例1、用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例。看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码。我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类。
1 2 3 4 5 6 7 // Java 8之前: new Thread( new Runnable() { @Override public void run() { System.out.println( "Before Java8, too much code for too little to do" ); } }).start(); 1 2 //Java 8方式: new Thread( () -> System.
在nginx里通过header进行分流 应用场景, 如想灰度部分用户到另一个服务器, 则让这些用户带上指定header, 然后在nginx里通过header判断, 进行分流 实现思路有两种 1. ------------------------------ if (...) rewrite 跳到内部location location 里做反向代理 要点: rewrite不支持post, 正确的说, 在post下, 只支持站内重写url, 站外的话重写url的话, 会丢掉body内容, 所以才要重定向到站到的location, 再做proxy_pass 在控制台使用有个问题还没解决, 请求第1次会一直没响应挂住, 第2次会正常返回便带一个warn, 请求第3次会一直没响应挂住, 第4次会正常返回便带一个warn, 请求第5次会一直没响应挂住, 第6次会正常返回便带一个warn warn信息如下: 六月 14, 2017 9:45:22 上午 org.apache.http.client.protocol.ResponseProcessCookies processCookies WARNING: Cookie rejected: "[version: 0][name: JSESSIONID][value: 9E2CB0E52952B53E554CAB4743D92C01][domain: 192.168.25.217][path: /demo_7/][expiry: null]". Illegal path attribute "/demo_7/". Path of origin: "/demo_8/listheader.jsp" 2. ------------------------------ if (...) proxy_pass 要点: 在if里做proxy_pass, 只能纯域名, 如http://192.168.25.217:8080; 不能有任何uri成份, 如http://192.168.25.217:8080/abc; 原因是 默认location /, 第一种 ------------------------------ 完整配置 注意testuser_8的变化 server {
socket接口,例如recv接口会做2件事情: 1.检查buffer是否有数据,有则复制清除返回 2.没有数据,则进入睡眠模式,当超时、数据到达、发生错误则唤醒进程处理 采用睡眠来等待,发生信号的时候进程会被唤醒,socket接口唤醒后检查有无未处理的信号(signal_pending)会返回EINTR错误。
处理方式,无需理会,重新运行该函数。 以下为封装好的函数处理,引用wrap.h,替换对应的函数名即可.
wrap.h
#ifndef __WRAP_H_ #define __WRAP_H_ void perr_exit(const char *s); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); void Bind(int fd, const struct sockaddr *sa, socklen_t salen); void Connect(int fd, const struct sockaddr *sa, socklen_t salen); void Listen(int fd, int backlog); int Socket(int family, int type, int protocol); ssize_t Read(int fd, void *ptr, size_t nbytes); ssize_t Write(int fd, const void *ptr, size_t nbytes); void Close(int fd); ssize_t Readn(int fd, void *vptr, size_t n); ssize_t Writen(int fd, const void *vptr, size_t n); #endif wrap.
VLAN间通信配置与管理
划分VLAN的目的是为了隔离同一网段中各主机间的直接二层通信,以缩小广播域。但在大多数情况下,不同VLAN中的主机又需要相互通信。为达到既二层隔离,又互相通信,华为交换机提供3种解决方案:配置三层VLANIF接口、三层以太网子接口、VLAN Switch三种实现VLAN间通信。
一、两种VLAN间通信方式
VLAN间的三层通信存在两种不同的情形:一是相互通信的不同VLAN同处于一个交换机上,二是相互通信的不同VLAN处于不同的交换机上。
1、同一台交换机上的VLAN间通信
如上图6-18,VLAN2~4在同一个三层交换机(也可以是路由器上)。此时要实现3个VLAN间的三层通信只需在该三层交换机为这3个VLAN各自配置VLANIF接口IP地址(要求在不同IP子网中)即可,因为在华为交换机中IP路由功能是一直启用的,加上这些VLAN是直接连接在同一台三层交换机上,相当于直连路由,所以无需其他额外配置就可以实现同一台交换机上不同VLAN间的三层互通。
2、不同交换机上的VLAN间通信
如图6-19,VLAN2~4不仅在同一台三层交换机(也可以是路由器)上有,而且在不同的三层交换机上也有,这就涉及跨三层设备的VLAN间通信问题。如果相互通信的不同VLAN位于不同的三层交换机上,不仅要为各VLAN配置VLANIF接口IP地址(不同交换机中的相同VLAN各自可以配置一个同网段的VLANIF接口IP地址),还要在三层设备上配置到达各个VLANIF接口所在网段的可达路由(可以是静态路由,也可以是各种动态路由)。
二、VLAN间通信方案及实现原理
1、三层VLANIF接口方案
这是一种通过计算机网络体系结构中第三层(网络层)来实现VLAN间通信的解决方案。每个VLAN都可配置一个三层VLANIF逻辑接口,而这些VLANIF接口作为对应VLAN内部主机的缺省网关,通过三层交换机内部的IP路由功能可以实现同一交换机上不同VLAN的三层互通,不同交换机上不同VLAN间的三层互通需要配置各VLANIF接口所在网段间的路由。
如上图,Device交换机上划分了两个VLAN:VLAN2和VLAN3,可通过如下配置实现VLAN间互通:
(1)在Device上创建两个VLANIF接口并配置VLANIF接口的IP地址,但这两个VLANIF接口对应的IP地址不能再同一网段。
(2)将各VLAN中的用户设备缺省网关设置为所属VLAN对应VLANIF接口的IP地址。
以位于VLAN2中的主机A向位于VLAN3中的主机C发起通信为例,通过VLANIF接口进行VLAN间三层互通的基本原理:
(1)在主机A向主机C发送的数据包到了网络层后,主机A先将包中的目的IP地址——主机C的IP地址和自己所在网段进行比较。
(2)发现主机C和自己不在同一个子网,于是主机A以广播方式在本子网内发送一个ARP请求帧,其目的是查寻自己的网关——VLANIF2接口的MAC地址。
(3)VLANIF2接口经过与ARP请求帧中的目的IP地址进行比较,发现自己的IP地址与其一致,接收该ARP请求帧,然后以单播方式向主机A返回一个ARP应答帧,帧中的源MAC地址即为VLANIF2的MAC地址。
(4)在主机A接收由VLANIF2接口返回的ARP应答帧后从中学习到了VLANIF2接口的MAC地址。
(5)主机A利用所获得的网关VLANIF2接口的MAC地址,重新进行数据帧封装,把帧中的目的MAC改为VLANIF2接口MAC地址,目的IP仍为主机C的IP地址,然后发送给网关——VLANIF2接口。
(6)Device交换机在收到该数据帧后进行三层转发,发现帧中的目的IP地址——主机C的IP地址为直连路由,数据帧直接通过该主机的网关——VLANIF3接口进行转发。
(7)VLANIF3接口作为VLAN3内主机的网关,在收到数据帧后如果已有主机C的IP地址与MAC地址映射表,则直接发送给主机C,否则VLANIF3接口先在VLAN3内以广播方式发送一个ARP请求帧,查寻主机C的MAC地址。
(8)主机C在收到ARP广播帧后向VLANIF3接口返回一个ARP应答帧。
(9)VLANIF3接口在收到主机C发来的ARP应答帧后再次进行数据帧封装,把帧中的目的MAC地址改为主机C的真实MAC地址(其他不变),然后把主机A发来的数据帧发送给主机C。这样主机A之后要发给C的数据帧都先发送给网关,由网关——VLANIF3接口做三层转发。
主机C与主机A之间的通信原理一样,最终实现VLAN间的三层互通。
2、三层以太网子接口方案
三层以太网子接口是一种同时具备三层以太网物理接口和二层以太网物理接口双重特性的逻辑接口。即它具有三层以太网物理接口的三层路由功能,同时又具有二层以太网物理接口封装VLAN标签的特性。通过三层以太网子接口就可以实现不同VLAN间的三层互通,也就是通常所说的“单臂路由”,在三层交换机和路由器中均可实现。
该方案仅5700HI和5710Ei子系列、S7700、S9300和S9700系列支持。
如上图,DeviceA为支持配置子接口的三层设备,DeviceB为二层交换设备。LAN通过DeviceB的二层以太网接口与DeviceA的三层以太网接口相连。连接在DeviceB上的用户主机被划分到两个VLAN:VLAN2和VLAN3.可通过如下配置实现VLAN间互通:
(1)在DeviceA与DeviceB相连的三层以太网接口上创建两个子接口Port1.1和Port1.2,并配置802.1Q封装与VLAN2和VLAN3分别对应。
(2)为以上这两个子接口配置与各自所属VLAN对应网段的IP地址。
(3)将DeviceB与DeviceA相连的二层以太网接口类型配置为Trunk或Hybrid类型,并同时允许VLAN2和VLAN3的通过。
(4)将VLAN2和VLAN3中的用户设备的缺省网关设置为所属VLAN对应三层以太网子接口的IP地址。
现在同样以主机A向主机C发起通信为例介绍三层以太网子接口的VLAN间通信方案的基本原理(其实基本过程与VLANIF接口VLAN间通信方案一样,只不过这里的网关是各VLAN所对应的子接口)。具体流程:
(1)在主机A向主机C发送的数据包到了网络层后,主机A先将包中的目的IP地址——主机C的IP地址和自己所在网段进行比较。
(2)发现主机C和自己不在同一个子网,于是主机A以广播方式在本子网内发送一个ARP请求帧,其目的是查寻自己的网关——VLAN2对应的Port1.1子接口的MAC地址。
(3)Port1.1子接口经过与ARP请求帧中的目的IP地址进行比较,发现自己的IP地址与其一致,接收该ARP请求帧,然后以单播方式向主机A返回一个ARP应答帧,帧中的源MAC地址即为Port1.1子接口的MAC地址。
(4)在主机A接收由Port1.1子接口返回的ARP应答帧后从中学习到了Port1.1子接口的MAC地址。
(5)主机A利用所获得的网关Port1.1子接口的MAC地址,重新进行数据帧封装,把帧中的目的MAC改为Port1.1子接口MAC地址,目的IP仍为主机C的IP地址,然后发送给网关——Port1.1子接口。
(6)DeviceA交换机在收到该数据帧后进行三层转发,发现帧中的目的IP地址——主机C的IP地址为直连路由,数据帧直接通过该主机的网关——VLAN3对应的Por1.2子接口进行转发。
(7)Port1.2子接口作为VLAN3内主机的网关,在收到数据帧后如果已有主机C的IP地址与MAC地址映射表,则直接发送给主机C,否则Port1.2子接口先在VLAN3内以广播方式发送一个ARP请求帧,查寻主机C的MAC地址。
(8)主机C在收到ARP广播帧后向Port1.2子接口返回一个ARP应答帧。
(9)Port1.2子接口在收到主机C发来的ARP应答帧后再次进行数据帧封装,把帧中的目的MAC地址改为主机C的真实MAC地址(其他不变),然后把主机A发来的数据帧发送给主机C。这样主机A之后要发给C的数据帧都先发送给网关,由网关——Port1.2子接口做三层转发。
3、VLAN Switch方案
通过VLAN Switch(VLAN交换)也可实现不同VLAN间的通信。VLAN交换是一种按照VLAN标签进行数据转发的技术,需要预先在网络中的各交换机上建立一条静态转发路径。当交换机接收到符合转发条件的VLAN数据后,根据VLAN交换表将报文直接转发到相应的出接口,无需查看MAC地址表,提高转发效率及安全性,有效避免MAC地址攻击及广播风暴。
仅S7700以上高端S系列交换机支持。
VLAN交换功能如下:
(1)添加外层VLAN标签功能,即VLANSwitch stack-vlan功能。
(2)在不同接口之间转换外层VLAN标签,即VLANSwitch Switch-vlan功能。
VLAN Switch stack-vlan功能与VLANStacking(VLAN堆叠)功能类似,也是一种针对用户不同VLAN封装外层VLAN标签的二层技术。
VLAN Switch switch-vlan功能与VLAN Mapping(VLAN映射)功能类似。
三、配置通过VLANIF接口实现VLAN间通信
VLANIF是逻辑三层口,配置IP地址后可实现网络层互通。通过VLANIF接口实现VLAN间通信需要为每个VLAN创建对应的逻辑接口VLANIF接口,并为每个VLANIF接口配置IP地址实现三层互通。为了成功实现VLAN间的三层互通,VLAN内用户主机的缺省网关必须对应VLANIF接口的IP地址。
示例:配置VLANIF2接口的主IP地址为10.1.1.2,从IP地址为11.1.1.3,子网掩码都为255.0.0.0。
<Huawei>system-view
[Huawei]interface vlanif 2
[Huawei-Vlanif2]ip address 10.
以下内容转载或参考自
http://blog.csdn.net/xuancailinggan/article/details/50373415
http://blog.csdn.net/xuly_29/article/details/52247567
说来惭愧,好多群友问这个问题,因为我用的minGW编译器,所以这个问题对我来说是不存在,后来终于想尝试用下vs版的qt了。
好了不多说,上代码:
就这一句话,直接报错说常量中有换行符,我滴天,其实呢,这个是编译器作怪,vs版本的编译器不认汉字!坑爹吧……
修改一下设置:
然后重新编译,正常情况下是可以的哦。但是显然不可以,这里是QT的一个bug,你需要找到汉字,随便找几个就行,重新打一下,然后编译就好了。
来下总结吧:
首先,要想用中文,你要设置编码是带bom的,这样写出来的代码没有任何问题。
如果你已经开写,或者用的别人的代码,你需要设置以后再选几个字重新打一下。选几个就行,别几万的汉字你都打了……那还不如重写呢。
正常运行了吧,不过下面这个还是乱码的,vs坑爹啊……支持开源,果断minGW吧,少年们。
在使用gcc/mingw或clang作为编译器时不会出现,如果把环境换成以MSVC编译就出现此错误.
具体为:
C4819:该文件包含不能在当前代码页(936)中表示的字符.请将该文件保存为Unicode格式以防止数据丢失.
C2001:常量中有换行符
问题所在是源代码中的中文字符.
如果在QT Creator里Select Encoding...
经常会出现错误: Error:Could not decode "XXX.cpp" with "XXX"-encoding . Editing not possible.
并且源代码中的中文会变乱码.
解决方法:
用Visual Studio打开出错源代码.
文件->高级保存选项->编码,
把编码由"Uncode (UTF-8 无签名) - 代码页65001"
换成
"Uncode (UTF-8 带签名) - 代码页65001"
确定后保存.
在QT Creator里可以正确显示中文并且不会出错"常量中有换行符"的错误
根据Net Applications的数据,Windows系统当前的市场份额为88.77%,30天就跌了1.68%。排在第二位的是Mac OS X,市场份额为9.57%;Linux第三,市场份额1.65%。4月份期间,苹果的操作系统获得了比较多的份额,上升1.8%,Linux则是从 1.78%跌至1.65%的。
这个数字应该表明,有一部分Windows用户最近选择了苹果的OS X,虽然并不清楚具体是多少。实际上,一个操作系统平台在一个月的时间内就下跌1-2个百分点的份额是很正常的,但在Net Applications看来,这是Windows家族系统首次跌破90%大关——原本Windows 10对整个Windows家族应该是有所助力的。
Windows市场份额最近一轮下跌是从去年12月份开始的,从11月的91.39%下跌至91.32%;今年1月、2月、3月也还在持续下跌,这三个月 Windows的市场份额分别是90.61%、90.45%和90.45%。所以本次下跌也是近1年来,Windows遭遇的最大滑坡。
在整个Windows系统中,Windows 7持续成为家族中的领跑者。Windows 7的市场份额正在稳步下滑,原本这是Windows 10获得市场份额的正常现象。不过这也可能是Windows整个家族市场份额下滑的重要原因。另外,许多用户开始将iOS和Android设备作为PC的 备选方案,也可能是Windows系统市占率下跌的原因。
====================================分割线================================
文章转载自 开源中国社区[http://www.oschina.net]
前言:虽然SQL有一套公共的标准,但是不同的数据库生产商在实现上还是存在较大差异,以序列为例,如果查询序列,ORACLE和DB2就存在
较大差异。这种差异,对于开发人员或者运维人员来说,是很痛苦的。最直接的影响就是,我们每次使用时都要百度或者谷歌一下。
-- 首先,我们创建一个名称为SEQUENCE_AUTO_INCREMENT的序列
DROP SEQUENCE SEQUENCE_AUTO_INCREMENT; CREATE SEQUENCE SEQUENCE_AUTO_INCREMENT AS BIGINT START WITH 200000216 INCREMENT BY 1 MINVALUE 200000216 MAXVALUE 999999999 NO CYCLE CACHE 20 NO ORDER; -- 接下来,我们可以使用下面2种方式查询
SELECT NEXT VALUE FOR SEQUENCE_AUTO_INCREMENT AS ID FROM SYSIBM.SYSDUMMY1; 或者
VALUES NEXTVAL FOR SEQUENCE_AUTO_INCREMENT;
public class Solution { /** * @param grid a boolean 2D matrix * @return an integer */ public int numIslands(boolean[][] grids) { // Write your code here if(grids.length==0){ return 0; } int [][]grid=new int[grids.length][grids[0].length]; for(int i=0;i<grids.length;i++){ for(int j=0;j<grids[0].length;j++){ if(grids[i][j]){ grid[i][j]=1; }else{ grid[i][j]=0; } } } ArrayList<Point> list=new ArrayList<Point>(); int count=0; for(int i=0;i<grid.length;i++){ for(int j=0;j<grid[0].length;j++){ Point p=new Point(grid[i][j], 0,1); if(grid[i][j]==1){ if(list.isEmpty()){ p.where=++count; list.add(p); }else{ if(i>0){ Point temp=list.get(list.size()-grid[0].length); if(temp.where>0){ p.where=temp.where; } } if(j>0){ Point temp=list.
**
*第五层:运输层* **
1. 概述: (1)真正数据通信的意思其实是: 在主机的进程中, 由A主机的进程与B主机的进程进行数据交换的 过程而不是主机之间的数据交换. 很显然, 将一个通信过程分为这么多层, 是为了让底层给高层服务, 并将每一层的任务分配好. 更重要的是, 我们知道 一个主机当中有很多个进程同时在通信, 但是我们又只有一个运输层, 所以很明显, 运输层具有"复用"和"分用"功能, "复用"指的是这么多进程都只使用一个运输层来传输数据, 而"分用"指的是运输层收到数据后,能够准确地派递相应的数据给相应的进程. (2)在物理层, 链路层, 网络层都没有对数据的可靠传输进行把关, 所以这个任务也就留到了运输层上了. 运输层要对报文进行差错检测. (3)运输层的UDP协议: 又叫 用户数据报协议, UDP不提供可靠交付, 对给出的发送报文, 不需要任何确认. (4)运输层的TCP协议: 又叫 传输控制协议, TCP是一种面向连接的服务, 要很多确认报文. 并且TCP不提供广播和多播服务. 2. 端口
(1)历史: 在概述(1)中提到, 运输层有"分用"和"复用"功能, 所以对于每一个进程有一个标识号是非常重要的. 所以在运输层使用"协议端口号"可以解决这问题, 简称"端口". (2)分类: 端口分两种: 第一种叫熟知端口号(系统端口号), 这些是一些常用并且固定下来的应用程序端口, 例如(FTP:21, HTTP:80), 另外一种叫登记端口, 这类端口是要申请的. 3. UDP协议(用户数据报协议)
(1)概述: UDP是一种无连接, 尽最大努力交付的协议, 所以他不需要建立链接, 最重要的是, UDP协议是面向报文的, 也就是说, 对于应用层丢下来的数据, 和网络层传上来的数据, UDP协议对它都不做任何改动, 既不拆分, 也不合并. 直接去除或者加上 UDP协议的首部就继续下一步工作.
String fileRoot = "F:/testFile/createFile/boot"; File file = new File(fileRoot); file.mkdirs(); mkdirs会创建多级目录 ,针对上述代码来说,在执行mkdirs后会创建testFile createFile boot这几个文件夹
mkdir则不会创建多级目录,他只会在指定路径下创建文件夹。
如果执行file.mkdir()会报java.io.FileNotFoundException (系统找不到指定的路径。)
另附两种文件创建和写入的方法:
FileWriter fw = new FileWriter(file+"/"+"test.txt"); fw.write("文件测试"); fw.flush(); fw.close(); FileOutputStream fs = new FileOutputStream(file+"/"+"test.txt", true); fs.write("文件测试".getBytes()); fs.close(); 这两个的区别主要在于他们对字节的处理上,FileWriter是字符流,FileOutputStream 是字节流。 所谓字节流:每次读入或输出的是8位二进制。字符流:每次读入或输出的是16位二进制,即两个字节。
FileWrite的具体实现
(1)FileWriter继承自OutputStreamWriter,在FileWriter中除了构造函数并没有其它的方法,在FileWriter的构造函数中,会先封装出一个OutputStream传递给父类OutputStreamWriter构造出父类的对象,调用FileWriter的write方法,其实就是调用的OutputStreamWriter的write方法
(2)在OutputStreamWriter中有一个StreamEncoder对象,调用OutputStreamWriter的write方法,其实就是调用的StreamEncoder的write方法
(3)在StreamEncoder中有一个字节缓冲区,会先把准备写入目的的字符先转变为字节,等缓冲区满了或者流被刷新后,流中的数据就写到目的中去,所以在使用FileWrite进行文件写入的时候,需要执行flush()函数。
FileOutputStream 的具体实现
FileOutputStream直接继承自OutputStream,调用FileOutputStream的write方法的时候,实际上就在调用底层的写方法,把数据直接写到文件中去了,没有缓存。
古代紫#895b8a 茄子紺#824880 二藍#915c8b 京紫#9d5b8b 蒲葡#7a4171 若紫#bc64a4 紅紫#b44c97 梅紫#aa4c8f 菖蒲色#cc7eb1 紅藤色#cca6bf 浅紫#c4a3bf 紫水晶#e7e7eb 薄梅鼠#dcd6d9 暁鼠#d3cfd9 牡丹鼠#d3ccd6 霞色#c8c2c6 藤鼠#a6a5c4 半色#a69abd 薄色#a89dac 薄鼠#9790a4 鳩羽鼠#9e8b8e 鳩羽色#95859c 桔梗鼠#95949a 紫鼠#71686c 葡萄鼠#705b67 濃色#634950 紫鳶#5f414b 濃鼠#4f455c 藤煤竹#5a5359 滅紫#594255 紅消鼠#524748 似せ紫#513743 灰黄緑#e6eae3 蕎麦切色#d4dcd6 薄雲鼠#d4dcda 枯野色#d3cbc6 潤色#c8c2be 利休白茶#b3ada0 茶鼠#a99e93 胡桃染#a58f86 江戸鼠#928178 煤色#887f7a 丁子茶#b4866b 柴染#b28c6e 宗伝唐茶#a16d5d 砺茶#9f6f55 煎茶色#8c6450 銀煤竹#856859 黄枯茶#765c47 煤竹色#6f514c 焦茶#6f4b3e 黒橡#544a47 憲法色#543f32 涅色#554738 檳榔子染#433d3c 黒鳶#432f2f 赤墨#3f312b 黒紅#302833白#ffffff 胡粉色#fffffc 卯の花色#f7fcfe 白磁#f8fbf8 生成り色#fbfaf5 乳白色#f3f3f3 白練#f3f3f2 素色#eae5e3 白梅鼠#e5e4e6 白鼠#dcdddd 絹鼠#dddcd6 灰青#c0c6c9 銀鼠#afafb0 薄鈍#adadad 薄墨色#a3a3a2 錫色#9ea1a3 素鼠#9fa0a0 鼠色#949495 源氏鼠#888084 灰色#7d7d7d 鉛色#7b7c7d 鈍色#727171 墨#595857 丼鼠#595455 消炭色#524e4d 藍墨茶#474a4d 羊羹色#383c3c 蝋色#2b2b2b 黒#2b2b2b 烏羽色#180614 鉄黒#281a14 濡羽色#000b00 黒壇#250d00 憲法黒茶#241a08 暗黒色#16160e 萌葱色#006e54 花緑青#00a381 翡翠色#38b48b 青緑#00a497 水浅葱#80aba9 錆浅葱#5c9291 青碧#478384 御召茶#43676b 湊鼠#80989b 高麗納戸#2c4f54 百入茶#1f3134 錆鼠#47585c 錆鉄御納戸#485859 藍鼠#6c848d 錆御納戸#53727d 舛花色#5b7e91 熨斗目花色#426579 御召御納戸#4c6473 鉄御納戸#455765 紺鼠#44617b 藍鉄#393f4c 青褐#393e4f 褐返#203744 褐色#4d4c61 月白#eaf4fc 白菫色#eaedf7 白花色#e8ecef 藍白#ebf6f7 白藍#c1e4e9 水色#bce2e8 瓶覗#a2d7dd 秘色色#abced8 空色#a0d8ef 勿忘草色#89c3eb 青藤色#84a2d4 白群#83ccd2 浅縹#84b9cb 薄花色#698aab 納戸色#008899 浅葱色#00a3af 花浅葱#2a83a2 新橋色#59b9c6 天色#2ca9e1 露草色#38a1db 青#0095d9 薄藍#0094c8 縹色#2792c3 紺碧#007bbb 薄群青#5383c3 薄花桜#5a79ba 群青色#4c6cb3 杜若色#3e62ad 瑠璃色#1e50a2 薄縹#507ea4 瑠璃紺#19448e 紺瑠璃#164a84 藍色#165e83 青藍#274a78 深縹#2a4073 紺色#223a70 紺青#192f60 留紺#1c305c 濃藍#0f2350 鉄紺#17184b 漆黒#0d0015 淡藤色#bbc8e6 藤色#bbbcde 紅掛空色#8491c3 紅碧#8491c3 紺桔梗#4d5aaf 花色#4d5aaf 紺藍#4a488e 紅桔梗#4d4398 桔梗色#5654a2 藤納戸#706caa 紅掛花色#68699b 紫苑色#867ba9 白藤色#dbd0e6 藤紫#a59aca 菫色#7058a3 青紫#674598 菖蒲色#674196 竜胆色#9079ad 江戸紫#745399 本紫#65318e 葡萄色#522f60 深紫#493759 紫黒#2e2930 紫#884898 薄葡萄#c0a2c7 紫紺#460e44 暗紅色#74325c 桑の実色#55295b 黄金#e6b422 櫨染#d9a62e 黄朽葉色#d3a243 山吹茶#c89932 芥子色#d0af4c 豆がら茶#8b968d 麹塵#6e7955 山鳩色#767c6b 利休鼠#888e7e 海松茶#5a544b 藍海松茶#56564b 藍媚茶#56564b 千歳茶#494a41 岩井茶#6b6f59 仙斎茶#474b42 黒緑#333631 柳煤竹#5b6356 樺茶色#726250 空五倍子色#9d896c 生壁色#94846a 肥後煤竹#897858 媚茶#716246 白橡#cbb994 亜麻色#d6c6af 榛色#bfa46f 灰汁色#9e9478 利休茶#a59564 鶯茶#715c1f 木蘭色#c7b370 砂色#dcd3b2 油色#a19361 利休色#8f8667 梅幸茶#887938 璃寛茶#6a5d21 黄海松茶#918754 菜種油色#a69425 青朽葉#ada250 根岸色#938b4b 鶸茶#8c8861 柳茶#a1a46d 海松色#726d40 鶯色#928c36 緑黄色#dccb18 鶸色#d7cf3a 抹茶色#c5c56a 若草色#c3d825 黄緑#b8d200 若芽色#e0ebaf 若菜色#d8e698 若苗色#c7dc68 青丹#99ab4e 草色#7b8d42 苔色#69821b 萌黄#aacf53 苗色#b0ca71 若葉色#b9d08b 松葉色#839b5c 夏虫色#cee4ae 鶸萌黄#82ae46 柳色#a8c97f 青白橡#9ba88d 柳鼠#c8d5bb 裏葉柳#c1d8ac 山葵色#a8bf93 老竹色#769164 白緑#d6e9ca 淡萌黄#93ca76 柳染#93b881 薄萌葱#badcad 深川鼠#97a791 若緑#98d98e 浅緑#88cb7f 薄緑#69b076 青鈍#6b7b6e 青磁鼠#bed2c3 薄青#93b69c 錆青磁#a6c8b2 緑青色#47885e 千歳緑#316745 若竹色#68be8d 緑#3eb370 常磐色#007b43 千草鼠#bed3ca 千草色#92b5a9 青磁色#7ebea5 青竹色#7ebeab 常磐緑#028760 木賊色#3b7960 天鵞絨#2f5d50 虫襖#3a5b52 革色#475950 深緑#00552e 鉄色#005243 小豆色#96514d 枯茶#8d6449 饴色#deb068 骆驼色#bf794e 土色#bc763c 黄唐色#b98c46 桑染#b79b5b 栌色#b77b57 黄橡#b68d4c 丁字染#ad7d4c 香染#ad7d4c 枇杷茶#ae7c4f 芝翫茶#ad7e4e 焦香#ae7c58 胡桃色#a86f4c 渋纸色#946243 朽葉色#917347 桑茶#956f29 路考茶#8c7042 国防色#7b6c3e 伽羅色#d8a373 江戸茶#cd8c5c 樺色#cd5e3c 紅鬱金#cb8347 土器色#c37854 狐色#c38743 黄土色#c39143 琥珀色#bf783a 赤茶#bb5535 代赭#bb5520 煉瓦色#b55233 雀茶#aa4f37 団十郎茶#9f563a 柿渋色#9f563a 紅鳶#9a493f 灰茶#98623c 茶色#965042 檜皮色#965036 鳶色#95483f 柿茶#954e2a 弁柄色#8f2e14 赤錆色#8a3319 褐色#8a3b00 栗梅#852e19 紅檜皮#7b4741 海老茶#773c30 唐茶#783c1d 栗色#762f07 赤銅色#752100 錆色#6c3524 赤褐色#683f36 茶褐色#664032 栗皮茶#6d3c32 黒茶#583822 葡萄茶#6c2c2f 葡萄色#640125 萱草色#f8b862 柑子色#f6ad49 金茶#f39800 蜜柑色#f08300 鉛丹色#ec6d51 黄丹#ee7948 柿色#ed6d3d 黄赤#ec6800 人参色#ec6800 橙色#ee7800 照柿#eb6238 赤橙#ea5506 金赤#ea5506 朱色#eb6101 小麦色#e49e61 丹色#e45e32 黄茶#e17b34 肉桂色#dd7a56 赤朽葉色#db8449 黄櫨染#d66a35 蒲公英色#ffd900 黄色#ffd900 中黄#ffea00 菜の花色#ffec47 黄檗色#fef263 卵色#fcd575 花葉色#fbd26b 刈安色#f5e56b 玉蜀黍色#eec362 金糸雀色#ebd842 黄支子色#ffdb4f 支子色#fbca4d 向日葵色#fcc800 山吹色#f8b500 鬱金色#fabf14 藤黄#f7c114 金色#e6b422 古代紫#895b8a 茄子紺#824880 二藍#915c8b 京紫#9d5b8b 蒲葡#7a4171 若紫#bc64a4 紅紫#b44c97 梅紫#aa4c8f 菖蒲色#cc7eb1 紅藤色#cca6bf 浅紫#c4a3bf 紫水晶#e7e7eb 薄梅鼠#dcd6d9 暁鼠#d3cfd9 牡丹鼠#d3ccd6 霞色#c8c2c6 藤鼠#a6a5c4 半色#a69abd 薄色#a89dac 薄鼠#9790a4 鳩羽鼠#9e8b8e 鳩羽色#95859c 桔梗鼠#95949a 紫鼠#71686c 葡萄鼠#705b67 濃色#634950 紫鳶#5f414b 濃鼠#4f455c 藤煤竹#5a5359 滅紫#594255 紅消鼠#524748 似せ紫#513743 灰黄緑#e6eae3 蕎麦切色#d4dcd6 薄雲鼠#d4dcda 枯野色#d3cbc6 潤色#c8c2be 利休白茶#b3ada0 茶鼠#a99e93 胡桃染#a58f86 江戸鼠#928178 煤色#887f7a 丁子茶#b4866b 柴染#b28c6e 宗伝唐茶#a16d5d 砺茶#9f6f55 煎茶色#8c6450 銀煤竹#856859 黄枯茶#765c47 煤竹色#6f514c 焦茶#6f4b3e 黒橡#544a47 憲法色#543f32 涅色#554738 檳榔子染#433d3c 黒鳶#432f2f 赤墨#3f312b 黒紅#302833白#ffffff 胡粉色#fffffc 卯の花色#f7fcfe 白磁#f8fbf8 生成り色#fbfaf5 乳白色#f3f3f3 白練#f3f3f2 素色#eae5e3 白梅鼠#e5e4e6 白鼠#dcdddd 絹鼠#dddcd6 灰青#c0c6c9 銀鼠#afafb0 薄鈍#adadad 薄墨色#a3a3a2 錫色#9ea1a3 素鼠#9fa0a0 鼠色#949495 源氏鼠#888084 灰色#7d7d7d 鉛色#7b7c7d 鈍色#727171 墨#595857 丼鼠#595455 消炭色#524e4d 藍墨茶#474a4d 羊羹色#383c3c 蝋色#2b2b2b 黒#2b2b2b 烏羽色#180614 鉄黒#281a14 濡羽色#000b00 黒壇#250d00 憲法黒茶#241a08 暗黒色#16160e 萌葱色#006e54 花緑青#00a381 翡翠色#38b48b 青緑#00a497 水浅葱#80aba9 錆浅葱#5c9291 青碧#478384 御召茶#43676b 湊鼠#80989b 高麗納戸#2c4f54 百入茶#1f3134 錆鼠#47585c 錆鉄御納戸#485859 藍鼠#6c848d 錆御納戸#53727d 舛花色#5b7e91 熨斗目花色#426579 御召御納戸#4c6473 鉄御納戸#455765 紺鼠#44617b 藍鉄#393f4c 青褐#393e4f 褐返#203744 褐色#4d4c61 月白#eaf4fc 白菫色#eaedf7 白花色#e8ecef 藍白#ebf6f7 白藍#c1e4e9 水色#bce2e8 瓶覗#a2d7dd 秘色色#abced8 空色#a0d8ef 勿忘草色#89c3eb 青藤色#84a2d4 白群#83ccd2 浅縹#84b9cb 薄花色#698aab 納戸色#008899 浅葱色#00a3af 花浅葱#2a83a2 新橋色#59b9c6 天色#2ca9e1 露草色#38a1db 青#0095d9 薄藍#0094c8 縹色#2792c3 紺碧#007bbb 薄群青#5383c3 薄花桜#5a79ba 群青色#4c6cb3 杜若色#3e62ad 瑠璃色#1e50a2 薄縹#507ea4 瑠璃紺#19448e 紺瑠璃#164a84 藍色#165e83 青藍#274a78 深縹#2a4073 紺色#223a70 紺青#192f60 留紺#1c305c 濃藍#0f2350 鉄紺#17184b 漆黒#0d0015 淡藤色#bbc8e6 藤色#bbbcde 紅掛空色#8491c3 紅碧#8491c3 紺桔梗#4d5aaf 花色#4d5aaf 紺藍#4a488e 紅桔梗#4d4398 桔梗色#5654a2 藤納戸#706caa 紅掛花色#68699b 紫苑色#867ba9 白藤色#dbd0e6 藤紫#a59aca 菫色#7058a3 青紫#674598 菖蒲色#674196 竜胆色#9079ad 江戸紫#745399 本紫#65318e 葡萄色#522f60 深紫#493759 紫黒#2e2930 紫#884898 薄葡萄#c0a2c7 紫紺#460e44 暗紅色#74325c 桑の実色#55295b 黄金#e6b422 櫨染#d9a62e 黄朽葉色#d3a243 山吹茶#c89932 芥子色#d0af4c 豆がら茶#8b968d 麹塵#6e7955 山鳩色#767c6b 利休鼠#888e7e 海松茶#5a544b 藍海松茶#56564b 藍媚茶#56564b 千歳茶#494a41 岩井茶#6b6f59 仙斎茶#474b42 黒緑#333631 柳煤竹#5b6356 樺茶色#726250 空五倍子色#9d896c 生壁色#94846a 肥後煤竹#897858 媚茶#716246 白橡#cbb994 亜麻色#d6c6af 榛色#bfa46f 灰汁色#9e9478 利休茶#a59564 鶯茶#715c1f 木蘭色#c7b370 砂色#dcd3b2 油色#a19361 利休色#8f8667 梅幸茶#887938 璃寛茶#6a5d21 黄海松茶#918754 菜種油色#a69425 青朽葉#ada250 根岸色#938b4b 鶸茶#8c8861 柳茶#a1a46d 海松色#726d40 鶯色#928c36 緑黄色#dccb18 鶸色#d7cf3a 抹茶色#c5c56a 若草色#c3d825 黄緑#b8d200 若芽色#e0ebaf 若菜色#d8e698 若苗色#c7dc68 青丹#99ab4e 草色#7b8d42 苔色#69821b 萌黄#aacf53 苗色#b0ca71 若葉色#b9d08b 松葉色#839b5c 夏虫色#cee4ae 鶸萌黄#82ae46 柳色#a8c97f 青白橡#9ba88d 柳鼠#c8d5bb 裏葉柳#c1d8ac 山葵色#a8bf93 老竹色#769164 白緑#d6e9ca 淡萌黄#93ca76 柳染#93b881 薄萌葱#badcad 深川鼠#97a791 若緑#98d98e 浅緑#88cb7f 薄緑#69b076 青鈍#6b7b6e 青磁鼠#bed2c3 薄青#93b69c 錆青磁#a6c8b2 緑青色#47885e 千歳緑#316745 若竹色#68be8d 緑#3eb370 常磐色#007b43 千草鼠#bed3ca 千草色#92b5a9 青磁色#7ebea5 青竹色#7ebeab 常磐緑#028760 木賊色#3b7960 天鵞絨#2f5d50 虫襖#3a5b52 革色#475950 深緑#00552e 鉄色#005243 小豆色#96514d 枯茶#8d6449 饴色#deb068 骆驼色#bf794e 土色#bc763c 黄唐色#b98c46 桑染#b79b5b 栌色#b77b57 黄橡#b68d4c 丁字染#ad7d4c 香染#ad7d4c 枇杷茶#ae7c4f 芝翫茶#ad7e4e 焦香#ae7c58 胡桃色#a86f4c 渋纸色#946243 朽葉色#917347 桑茶#956f29 路考茶#8c7042 国防色#7b6c3e 伽羅色#d8a373 江戸茶#cd8c5c 樺色#cd5e3c 紅鬱金#cb8347 土器色#c37854 狐色#c38743 黄土色#c39143 琥珀色#bf783a 赤茶#bb5535 代赭#bb5520 煉瓦色#b55233 雀茶#aa4f37 団十郎茶#9f563a 柿渋色#9f563a 紅鳶#9a493f 灰茶#98623c 茶色#965042 檜皮色#965036 鳶色#95483f 柿茶#954e2a 弁柄色#8f2e14 赤錆色#8a3319 褐色#8a3b00 栗梅#852e19 紅檜皮#7b4741 海老茶#773c30 唐茶#783c1d 栗色#762f07 赤銅色#752100 錆色#6c3524 赤褐色#683f36 茶褐色#664032 栗皮茶#6d3c32 黒茶#583822 葡萄茶#6c2c2f 葡萄色#640125 萱草色#f8b862 柑子色#f6ad49 金茶#f39800 蜜柑色#f08300 鉛丹色#ec6d51 黄丹#ee7948 柿色#ed6d3d 黄赤#ec6800 人参色#ec6800 橙色#ee7800 照柿#eb6238 赤橙#ea5506 金赤#ea5506 朱色#eb6101 小麦色#e49e61 丹色#e45e32 黄茶#e17b34 肉桂色#dd7a56 赤朽葉色#db8449 黄櫨染#d66a35 蒲公英色#ffd900 黄色#ffd900 中黄#ffea00 菜の花色#ffec47 黄檗色#fef263 卵色#fcd575 花葉色#fbd26b 刈安色#f5e56b 玉蜀黍色#eec362 金糸雀色#ebd842 黄支子色#ffdb4f 支子色#fbca4d 向日葵色#fcc800 山吹色#f8b500 鬱金色#fabf14 藤黄#f7c114 金色#e6b422
k8s集群新增节点机node3,有一个容器busybox运行在nod3上的,在k8s master主机上执行进行容器命令返回如下错误
$ kubectl exec -it busybox sh Error from server: error dialing backend: dial tcp: lookup node3 on 114.114.114.114:53: no such host 但跑到node主机上,进行容器却可以
$ doker exec -it containerid sh 百思不得其解,又重新确认一次node3上的docker和kubernetes配置,确认无误。最后在master主机的 /etc/hosts 上添加node3的ip和主机名,问题就解决了
192.168.100.53 node3
package com.y9zb.web.util; import com.y9zb.core.SplitSet; import com.y9zb.core.TimeUtil; import org.apache.poi.hssf.usermodel.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.util.LinkedHashMap; import java.util.List; import java.util.Map.Entry; /** * 导出Excel * @author Guang * */ public class PoiExcelUtil { private static final Logger logger =LoggerFactory.getLogger(PoiExcelUtil.class); /** * 导出Excel * @param excelName 要导出的excel名称 * @param list 要导出的数据集合 * @param fieldMap 中英文字段对应Map,即要导出的excel表头 * @param response 使用response可以导出到浏览器 * @return */ public static <T> Boolean export(String excelName,List<T> list,LinkedHashMap<String, String> fieldMap,HttpServletResponse response){ // 设置默认文件名为当前时间:年月日时分秒 if (excelName==null || excelName=="
最近见到p-value的频率有点高,之前也看到很多次了,基本当时懂了过几天就忘记了,整理下。
P值定义[from:百度百科]
P值即概率,反映某一事件发生的可能性大小。统计学根据显著性检验方法所得到的P 值,一般以P < 0.05 为有统计学差异, P<0.01 为有显著统计学差异,P<0.001为有极其显著的统计学差异。其含义是样本间的差异由抽样误差所致的概率小于0.05 、0.01、0.001。实际上,P值不能赋予数据任何重要性,只能说明某事件发生的机率。
P值解释[from:百度百科] P值
碰巧的概率
对无效假设
统计意义
P>0.05
碰巧出现的可能性大于5%
不能否定无效假设
两组差别无显著意义
P<0.05
碰巧出现的可能性小于5%
可以否定无效假设
两组差别有显著意义
P <0.01
碰巧出现的可能性小于1%
可以否定无效假设
两者差别有非常显著意义
P值的使用实例
实验考察一枚硬币是否均已。:
P:硬币是均匀的。
Q:在100次投掷中,得到90次正面,10次反面。
先说我们想证明什么?显然想证明硬币不均匀,把想证明的当作Ha,想证明的反面当作h0
在h0情况下得到Q(或者比Q更极端)的概率就是p-values,显然p-value越小,说明h0越“不靠谱”,也就是其反面ha(这里就是硬币不均匀)“相对更靠谱”。
所以p-value检验。思路上更类似“反证法”,但是不是严格逻辑反证,而是概率层面上的反证。通过假设出我们需要证明目标反面的情况。然后从情况推导出"出现最终观察现象"的概率非常低(5%)。就认为我们假设出的那个“证明目标反面的情况”不靠谱。从而证明“证明目标”是ok的。
参考:
标签归档:P-value:http://cos.name/tag/p-value/
P-Value P值的含义:http://www.cnblogs.com/emanlee/archive/2011/06/14/2080278.html
假设检验中的P值:http://baike.baidu.com/item/%E5%81%87%E8%AE%BE%E6%A3%80%E9%AA%8C%E4%B8%AD%E7%9A%84P%E5%80%BC
用过ubuntu的人都知道,ubuntu默认root密码是随机的,即每次开机都有一个新的root密码。我们可以在终端输入命令sudo passwd,然后输入当前用户的密码
给root用户设置密码 打开终端,输入命令sudo passwd,然后系统会让你输入新密码并确认,此时的密码就是root新密码。修改成功后,输入命令su root,再输入新的密码就ok了 分析 没有默认的,因为你还没给root设置密码,第一个user是在admin组,所以他可以给root设置密码,因此 root 设置密码 , so sudo passwd root [sudo] password for you :—> 输入你的密码,不会显示 Enter new UNIX password: — > 设置root 密码 Retype new UNIX password: 安装以后可以到用户和组里面去改,随便改的。要在登录时用root的话,可以在”登陆界面”里改,让管理员登陆系统的选项就可以了
参考文献 百度经验:http://jingyan.baidu.com/article/5225f26b0ac250e6fb09084e.html
遍历目标ul中的内容,如果发现已存在的则禁止添加. 按照普通的if else,条件每执行一次,满足条件的添加,但如果ul里有多个内容,那么在遍历的时候,语句会多次运行,满足条件的也会多次添加.如何在循环语句执行完成之后再写入内容呢. 我们可以在循坏外部设置一个值,当循环内符合条件时让他发生变化,最后通过判断值来添加内容. function addli() { var factor = $('.add-label-list'); var label = $('#custom-pjo li'); var ul = $('#custom-pjo'); var i = 0; $.each(label,function(num) { if( $.trim(label.eq(num).html()) == factor.val() ) { i = i+1; }else { i = i+0; } }); if(i == 0) { ul.append('<li class="choosed-category-list">'+factor.val()+'</li>'); }else { alert('添加失败'); } }
1、TCP连接
要想明白Socket连接,先要明白TCP连接。手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
建立起一个TCP连接需要经过“三次握手”:
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”.
2、HTTP连接
HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
3、SOCKET原理
3.1套接字(socket)概念
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
3.2 建立socket连接
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
4、SOCKET连接与TCP连接
创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。
5、Socket连接与HTTP连接
由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
由于苹果的安全策略问题,禁用了JavaScript中video的autoplay。所以通过javascript调用video.play()的时候,如果不是在onclick或者ontouch事件中调用的video.play(),那么播放将无效。
解决方法:
设置webview的选项
webView.mediaPlaybackRequiresUserAction = NO;
参考:https://stackoverflow.com/questions/12496144/can-you-autoplay-html5-videos-on-the-ipad
php计算当前时间到下个月的剩余天数 ps:本人亲测,阿里云2核4G5M的服务器性价比很高,新用户一块多一天,老用户三块多一天,最高可以买三年,感兴趣的可以戳一下:阿里云折扣服务器
//当前时间距离下个月还有多少天 function less_day() { $month_big = array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); //现在的月份 $date_month_old = (int)date('m',time()); //下个月的月份 $date_month_new = $date_month_old + 1; //下个月1号的时间戳 $date_time_new = strtotime('1 '.$month_big[$date_month_new-1].' '.date('Y',time())); //今天的时间戳 $date_time_old = strtotime(date('d',time()).' '.$month_big[$date_month_old-1].' '.date('Y',time())); //距下月剩余时间 $time_new = ($date_time_new - $date_time_old)/24/60/60-1; return $time_new; } header("Content-type: text/html; charset=utf-8"); echo '今天是:'.date('Y-m-d',time()).'<br/>'; echo '距离下个月还有:'.less_day().'天';
1)如果知道邮箱登录密码,直接点忘记密码输入两次邮箱密码即可
2)如果不知道邮箱登录密码,并且碰到换人用此电脑收发邮件,但需要查询前任历史邮件(当然是工作交接需要用到的而非盗看他人)。
这里就要用到星号密码查看器,查到FOXMAIL电脑里记忆的帐号密码,这时重置你的邮箱密码也是没有用的,只能看历史的,查询到原来邮箱密码即可重置
柯洁与AlphaGo的巅峰绝响落幕了,这无疑为近几年来很火的人工智能又添了一把柴。媒体上有很多文章分析AlphaGo所用的技术,但这次比赛对围棋的影响同样是十分深远的。 19岁的当今世界围棋第一人柯洁与重装上阵的AlphaGo之间的三番棋决战,再次将间歇性棋迷的我拉到电脑屏幕前,每一盘跟着对局双方不吃午饭地熬了几个小时。看到第三局开始不久柯洁脸上无奈和痛苦的表情、赛后新闻发布会上哽咽的发言,回想起一年前AlphaGo与李世石交战之际他笑谈前辈、指点纹枰的风采(气焰),我颇为动容。 迄今已四夺国际围棋大赛冠军和数次国内比赛冠军,自2015年起就位居国际棋手排名系统Go Ratings第一位,柯洁用傲人和稳定的成绩证明了他是职业棋手这个天才群体中的天才。以围棋为职业,天分仅仅是入场券,要想出类拔萃勤奋是必不可少的。当代棋手熟悉围棋的理论、定式、手筋,学习历史上遗留下来的大量棋谱,研究当下比赛实战谱和趋势,参加频繁的比赛和高密度的网上对弈,将过去棋手经历几十年攀上棋艺顶峰的道路压缩到十余年内完成,十六七岁就拿世界冠军已不是新闻。少时学棋的柯洁早早就立下了不仅要得冠军,还要成为世界围棋第一人的理想,天赋过人的他刻苦异常,“有时候累得啃个苹果,啃着啃着就睡着了”,在一次接受央视董卿采访时柯洁说。他的奋斗故事就像日本热血体育动漫的现实版,在频频击败昔日偶像李世石后,柯洁带着年轻人的志得意满说,“传奇是时候落幕了”。 然而就在柯洁以为可以快乐地做棋坛第一人的时候,AlphaGo横空出世。在它之前几十年人工智能在围棋领域里的有限进展一直让人类棋手有信心和理由轻视机器对手。上个世纪优秀的棋手能够让电脑25个子以上——想象一下百米赛跑一方让另一方99米。进入本世纪后,蒙特卡洛搜索和机器学习大幅提升了电脑的弈棋水平,2009年首次有程序能达到业余低段位。2012年和2013年,Zen和Crazy Stone分别在被让四子的情况下战胜了早已过巅峰的武宫正树和石田芳夫。2015年风云突变,AlphaGo首先在分先的情况下五局五胜职业二段棋手樊麾,彼时它在高段棋手眼里仍然下得保守,没有任何威胁。短短几个月后,AlphaGo就让事先称将5:0取胜的李世石尝到了1:4的败绩。对计算机的进步速度早已习惯的普通人都会断言这是人类赢AlphaGo的最后一局棋。职业棋手虽然也感到震惊,但局内人的身份和惯性令他们认为失败主要是由于李世石的轻敌和不熟悉人工智能的棋路,认真研究电脑的下法,琢磨程序的弱点,人类棋手还是能挽回颜面。很快,这些努力就显得是徒劳了。Master在网络快棋上对当今几乎所有一流高手取得60:0的战绩,随后DeepMind承认那是AlphaGo升级版,并披露它的实力已超越上一版三个子。这些都不容置疑地表明人类在电脑面前已无胜机,对于以围棋为事业的职业棋手们,感情上接受这一点是远比理性上承认它困难和痛苦。柯洁说AlphaGo不仅改变了他对围棋的认识,还改变了他对人生的看法,这应该是不少棋手的心声。经历十多年的学习和磨练后,棋手们基本达到自己的最高水准,往后再提高一小点都像田径比赛打破世界纪录一样困难,人类已达到了自己的极限。可是AlphaGo的棋力却从2014年诞生起持续飞速提升,远远地将人类甩在背后。现实太残酷,变化又来得太快。AlphaGo还需要最后的加冕礼——在正式比赛中赢得当今围棋第一人的柯洁。面对这答案近乎已经揭晓的挑战,人类的代表没有逃避的可能。 “我相信未来是属于人工智能的。可它始终都是冷冰冰的机器,与人类相比,我感觉不到它对围棋的热情和热爱。对它而言…它的热情——也只不过是运转速度过快导致CPU发热罢了。我会我用所有的热情去与它做最后的对决,不管面对再强大的对手——我也绝不会后退!至少这…最后一次…” 在决战前夕,柯洁于题为《最后的对决》的博文中写下了上面这段话。在万众棋迷的注视和见证奇迹的希望下,带着“必胜的信念和必死的决心”,柯洁使尽了浑身解数,下出了精彩棋局,结果还是许多人预料中的0:3。三局结束后的新闻发布会很简短,“我昨天晚上没睡好,想着怎样才能赢AlphaGo……我希望能做得更好,可惜没有做到……很多人今天都能下得比我好,所以我不觉得应该得到什么赞扬……我的情绪浮动,下得很糟糕。我希望能下得更好,很遗憾,以后也没有机会了……我今天输给AlphaGo,不觉得是什么双赢,可能和很多人的想法不一样……我会继续努力……”柯洁的情绪明显很低落,又要不断控制自己,强颜微笑。输棋的痛苦和失落、对自己比赛过程中情绪的起伏和表现的不满,让他流下了眼泪。 有些人或许会觉得,围棋不过是一种智力游戏,被人工智能超越又有多大关系。最容易想到的比喻就是,人跑不过自己发明的汽车,力气也没有举重机大。然而人不会因为这些机器的表现超过自己感到忧虑和惊讶,因为我们的祖先见识过大象,也早就知道自己跑不过马。人类对自己在身体的能力上不是冠军早就习以为常。人类作为万物之灵,骄傲的是自己拥有的心智。围棋所需的心智恰恰是长久以来被认为只有人类才具备。1997年深蓝击败了卡斯帕罗夫,给了人类类似的冲击,但是围棋在每步棋的可能下法数量和一局棋的着数都远超国际象棋,这使得前者所有可能的棋局数量达到10的761次方,而后者只有10的120次方,两者差距的10的600多次方是个惊人的数字。因为计算量的庞大,人类在下围棋时要更多地借助于直觉——对棋形和大局的感觉。虽然在计算广度和深度上有巨大的优势,现有的计算机仍然要想办法获得某种类似人的棋感,才能避免永无止境的计算。围棋的局面恰恰是极难评估的,一个棋子位置上的细微差别就可能造成整盘棋的天壤之别。直到AlphaGo问世前,计算机围棋界还还相信根据任意棋局准确判断孰优孰劣是不可能的。而依据谷歌发布的资料,AlphaGo通过机器学习获得的“直觉”如此精准,以至于不做后续计算,仅仅根据对个落子点的价值评估,就能战胜人类的一流棋手。 与在古代中国被列为琴棋书画之一、作为文人雅士陶冶情操的游戏不同,现在的职业围棋是残酷的胜负世界。年轻人因为计算力和精力的优势成为棋坛的主角,30岁的棋手就已是老将。与武侠小说里年纪越大功力越深的大师相比,棋手更像是体育场上吃青春饭的运动员。两个人面对面,几个小时里精心计算,就为在361个交叉点的棋盘上争得哪怕是半目的胜利,棋局终了,所有的心血都变成简单的一胜一负。一代棋手的目标是战胜李昌镐,新一代棋手的目标是超越李世石,围棋的最高技艺就在这似乎永恒的新老交替中传承和延续。突然,冠军奖杯被永远封存。在黄博士面前,任何棋手都不再有认为自己的棋着绝对好的自信。 对胜负的执着的另一面是对棋道的追求。围棋传入日本后,在重视传统、礼仪、等级和名誉,讲究静心追求极致的文化里,演化出了影响深远的棋道,形成了本因坊、井上、安井、林四大家。彼时的正式对弈数量很有限,双方也都极为重视,特别是一年一度的御城棋,关系到一大家棋手的名誉和利益,说是呕心沥血毫不夸张。进入现代,围棋组织和比赛的制度都有很大改变,但日本棋手很多仍旧继承了对棋道的追求,藤泽秀行“强烈的努力”题字和“棋道一百,我只知七”话语便是其代表。客观地说,这些追求的背后有一个隐含的前提,那就是围棋的奥秘难以穷尽,但是人可以努力进步,思考、练习、交流、对弈就是前进的途径。但是人工智能对棋手的碾压,表明这个更高的水平——棋道是可望而不可即的,更重要的是它是传统的方法无法达至的。所谓机器战胜了人,只不过是说计算机科学家和软件工程师用另一种人类无法实践只有计算机能进行的途径才能下出更能制胜的棋,然而讽刺的又是下棋的计算机对此毫无意识,毫无兴趣,毫不欣赏。这是对棋道的祛魅,也不可避免地对传统围棋文化造成冲击。 知道人下不过机器后,各大围棋比赛的赞助会不会减少?棋迷的热情会不会消减?以后学棋的模式会有怎样的改变?在机器频频战胜人类的日子里,与棋手个人的挫败感并存的还有笼罩在整个围棋界之上的迷茫。 所幸的是,阴云似乎已经开始散去。职业棋手的心理调适完成了。棋手们转而把AlphaGo视为老师,传统的思路被打破,棋盘上呈现出更多的可能。粉丝们的热情也不见受影响。自嘲为“过气网红和当红棋手”的柯洁,微博拥有350多万粉丝。过去他在上面晒日常,秀互动,开玩笑,除了颜值稍逊,完全不输于娱乐明星。一只阳光、快乐、对围棋热爱且有责任感的天才单身狗成为围棋在中国最好的推广大使。AlphaGo的异军突起一度让柯洁有些兴意阑珊,很少发微博。人机大战后喝了九个小时的酒,睡了两个小时,隔日战胜LG杯32强对手元晟溱后,棋士柯杰满血复活。 “现在才发觉…原来和人类下棋,是可以这么的轻松、自在、快乐…下围棋真好” 这条微博获得史无前例的20万点赞,1万5千多条评论。 甚至娱乐圈的反应更积极。由于众所周知的原因,中央电视台不直播人机大战,bilibili网站的讲解直播成为国内观看人数最多的平台,平均10万的在线数比YouTube网站的官方现场直播高出一个数量级。B站基友们送着辣条,撩着主播小姐姐,笑着卡通头套技术员,发送着“现在比分几比几”,“狗狗感觉到一股神秘的东方力量”,“阿尔法狗决定让单身狗一手”,“柯洁中午不吃饭,阿尔法狗应该用电池才公平”的弹幕。 围棋,这项古老的智力游戏,注定将延续它的魅力。
Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。用途也和服务的API对应。
1) ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源(图片,规则,等等)。
2) ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
3) ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。
4) ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例,变量,任务等等。
5) ACT_GE_*: 通用数据, 用于不同场景下。
资源库流程规则表
1) act_re_deployment 部署信息表
2) act_re_model 流程设计模型部署表
3) act_re_procdef 流程定义数据表
运行时数据库表
1) act_ru_execution 运行时流程执行实例表
2) act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
3) act_ru_task 运行时任务节点表
4) act_ru_variable 运行时流程变量数据表
历史数据库表
1) act_hi_actinst 历史节点表
2) act_hi_attachment 历史附件表
3) act_hi_comment 历史意见表
4) act_hi_identitylink 历史流程人员表
5) act_hi_detail 历史详情表,提供历史变量的查询
6) act_hi_procinst 历史流程实例表
7) act_hi_taskinst 历史任务实例表
若已知空间域某段距离上曲线的离散数据,如何求该段距离上曲线的变化频率?
1)将离散数据拷入Origin
2)在Analysis —— Signal Processing——FFT
3)关键是sample interval的设定,例如:1000个数据点,就设定为1/1000=0.001或1E-3
这样相当于这段距离为1秒采样所得数据,所以最终得到是 曲线的 频率/秒,也就是该段距离上的曲线变化周期。