ksh下自动补全命令方法

方法一: set -o vi 历史命令功能(esc -,esc +)自动补全文件名(esc \)。 方法二: set -o emacs 历史命令功能(ctrl-n,ctrl-p),自动补全文件名(按两次esc)。 找不到自动补全命令的功能,还是bash比较人性化。 来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26366371/viewspace-2062349/,如需转载,请注明出处,否则将追究法律责任。 转载于:http://blog.itpub.net/26366371/viewspace-2062349/

从文本导入海量数据(informix)(oracle->infomrix数据迁移)

从文本导入数据到informix数据一般使用SQL语句: load from file.dat insert into tablename; 但当导入的数据有好几百万甚至上千万条时用上面的方法产生大锁表,及至数据库锁不够,导致长事务无法导入。 一个解决的办法是使用dbload命令,以下为dbload的参数说明: #--------------------------------------------------------------------- #dbload Usage: # #dbload [-d dbname] [-c cfilname] [-l logfile] [-e errnum] [-n nnum] # [-i inum] [-s] [-p] [-r | -k] [-X] # # -d database name # -c command file name # -l bad row(s) log file # -e bad row(s) # before abort # -s syntax error check only # -n # of row(s) before commit # -p prompt to commit or not on abort # -i # or row(s) to ignore before starting # -r loading without locking table # -X recognize HEX escapes in character fields # -k loading with exclusive lock on table(s) #--------------------------------------------------------------------- 下面举一简单例子: 数据库名:dbsname load命令文件名:load.

sqlldr例子

导入核心数据: sqlload.sh: sqlldr userid=dpfm30/dpfm30 control=/oradata/zfht/dpfm30/control.ctl data=/oradata/zfht/dpfm30/$1 log=/oradata/zfht/dpfm30/log/$1_log.log bad=/oradata/zfht/dpfm30/log/$1_bad.log discard=/oradata/zfht/dpfm30/log/$1_discard.log direct=false skip_index_maintenance=true control: load data into table dpfm30_2014 append fields terminated by '|' optionally enclosed by '"' TRAILING NULLCOLS ---对于添加像entire这样的列非常有用 (DM30ACCT ,DM30ACCS ,DM30TXDT date "DD-MM-YY" ,DM30PTXSQ ,DM30CTXSQ ,DM30CCY ,DM30CLIPRO ,DM30AMT ,DM30CRDFLG ,DM30BALE ,DM30BALD ,DM30ATUNTT ,DM30OPNODE ,DM30CTFLG ,DM30DOCTYP ,DM30VOUN ,DM30PAGNO ,DM30ITEM ,DM30PRTFLG ,DM30PTXCD ,DM30TELID ,DM30CHKTEL ,DM30TOACCT ,DM30TOACCS ,DM30TXRMKC ,DM30TXRMKS ,DM30TXCOM ,DM30PRTNUM ,DM30CRDNO ) 导入时报错: ORA-01858: a non-numeric character was found where a numeric was expected 处理方法: 需要设置: export NLS_LANG="

安装最新版本的R

安装最新版本的R 步骤1:将最新版本路径导入sources.list中 步骤2:更新软件库 步骤3:安装驱动库 步骤4:安装R 步骤一 本文所用最新版本路径: linux下将路径导入: sudo vim /etc/apt/sources.list # 在末端加上 deb http://mirrors.ustc.edu.cn//CRAN/bin/linux/ubuntu/ xenial/ 步骤一注意事项 最新版本的镜像路径会变会失效,此时去官网看看最新的镜像路径,并选择适合自己的文件夹路径。 步骤二 更新软件库 sudo apt-get update 注意事项 报错 W: GPG error: http://mirrors.ustc.edu.cn//CRAN/bin/linux/ubuntu xenial/ InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 51716619E084DAB9 W: The repository 'http://mirrors.ustc.edu.cn//CRAN/bin/linux/ubuntu xenial/ InRelease' is not signed. 错误为缺少公钥xxxx,把公钥加上 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 51716619E084DAB9 安装驱动库 sudo apt-get install r-base-dev 安装R sudo apt-get install r-base-core 其他 apt-get install r-base-core: 运行报错 The following packages have unmet dependencies: r-base-core : Depends: libgfortran3 (>= 4.

Leetcode:189. Rotate Array(JAVA)

【问题描述】 Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. Note: Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. [show hint] Related problem: Reverse Words in a String II 【思路1】 三次反转,1:反转前部分,2:反转后部分,3:整个反转。 复杂度相对较高 【code】 public class Solution { public void rotate(int[] nums, int k) { int temp = k % nums.

最小生成树之MST性质

在数据结构上看到这个性质的时候并不是很理解,觉得很抽象,所以我决定记录一下,以免以后又不理解了。 其实就是一个 最优选择问题。 原性质描述如下: 假设N = (V,{ E })是一个连通网,U 是顶点集V的一个非空子集。若(u , v )是一条具有最小权值(代价)的边,其中u∈U, v∈V - U,则必存在一棵包含边(u,v)的最小生成树。 就先不画图了,现在把V分成U和V - U两个集合,想一下,现在已经有一棵生成树T了,所以在U和V - U之间一定有一条边连着,所以这种情况下V - U中的所有点一定是互相连通的,(u,v)这条边权最小,但是此刻并没有连着。那么就是V - U中的另一条边连接着这两个点集。那么假如把这条边换成(u ,v)了,一定比T的总权和小啊。就是酱紫。 这么说可能还有点不理解,结合一下反证法就知道了。 假设网N的任何一棵最小生成树都不包含(u,v)。设T是连通网上的一棵最小生成树,当将边(u,v)加入到T中时,由生成树的定义,T中必存在一条包含(u,v)的回路。另一方面,由于T是生成树,则在T上必存在另一条边(u’,v’),其中u’∈U,v’∈V - U,且u和u’之间,v和v’之间均有路径相通。删去边(u’,v’),便可消除上述回路,同时得到另一棵生成树T’。因为(u,v)的代价不高于(u’,v’),则T’的代价亦不高于T,T’是包含(u,v)的一棵最小生成树,和假设矛盾。

两个单链表交叉和判环问题

有两个单链表,只有数据,和下一个结点的信息。 首先判环 环不要只想到O型环,还有6型环。 可以用两个指针遍历单链表P1、P2。P1每次走一步,P2每次走两步。如果最后P2追上了P1,则有交叉。这个问题可以想象,两个人绕着操场跑步,第二个人比第一个人快,则第二个人一定会在某一圈与第一个人相遇。 具体可以考虑有一个10步的圈子,从1到10。然后两个人从1开始粗发。步骤如下 P1 以 1.2.3.4. 5. 6.7.8.9.10.1.2..重复 P2 以 2.4.6.8.10.2.4.6.8.10.重复 所以在P2在第二圈追上了P1。就是酱。 如果这个时候你说P2每次走3步会不会追的更快,那是不一定的。如果环的周长是偶数,而P2和P1相差奇数时,比如环周长为偶数,而P1、P2初始相差奇数步。(这块还没想明白) 然后判断交叉,如果有一个链表有环,有一个链表无环,则一定不交叉 判断是否交叉,有一个简单的办法是,先遍历完一个链表,记录下最后一个被访问的结点,然后遍历第二个链表,如果第二个链表最后也指向那个结点,则连个链表交叉。

c++中string 的replace用法

/*用法一: *用str替换指定字符串从起始位置pos开始长度为len的字符 *string& replace (size_t pos, size_t len, const string& str); */ int main() { string line = "this@ is@ a test string!"; line = line.replace(line.find("@"), 1, ""); //从第一个@位置替换第一个@为空 cout << line << endl; return 0; } 运行结果: /*用法二: *用str替换 迭代器起始位置 和 结束位置 的字符 *string& replace (const_iterator i1, const_iterator i2, const string& str); */ int main() { string line = "this@ is@ a test string!"; line = line.replace(line.begin(), line.begin()+6, "

android成长日记 11.详细学习了数据存储相关基础知识

2019独角兽企业重金招聘Python工程师标准>>> 其实很简单,数据存储分为三种,分别是文件存储,sharepreference.和数据库存储.下面来一一介绍. 文件存储,就是利用java中的输入输出流,把要存储的内容以文件的形式保存在手机中,它就仅仅是你写入的内容,他没有键值对.也就是说你不能索引,你只能全写全拿.细节分为写入文件,和从文件读取, 写入文件:首先你要有一个对象,BufferWriter对象调用他的.write(要写入的文件)方法来写入文件,但是这个对象需要一个outputSteamwriter对象才能建立.,,,,但是outputsteamWriter对象需要一个FileOutputSteam对象......但是fileOutputSteam对象需要使用openFileOtput(文件名.和模式.MODE_PRIVATE)来建立,从而可以写入了,我就操了,这他妈拐这么多弯道时为了啥啊. 读取文件:和上边差不太多,但是还是有区别的.首先你要一个BufferReader的对象,调用它的read()函数来读取,.但是这个对象你需要一个inputSteamreader对象来建立,,,,,,,但是inputSteamreader对象需要一个fileinputSteam对象.....fileinputSteam对象需要使用openfileinput(文件名),才能建立.从而实现,其实写代码的时候都是反着写的,一层一层的往里写,这里和写入的区别就是,读取是有返回值的....你就要建立一个对象StringBuilder对象.这个对象不能声明为null,(千万记住,要不会报错空指针)你需要new一个对象给它.剩下的就是最后把它再返回吧, 说一说如何遍历要读取的字符串:. FileInputStream in = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try { in = openFileInput("data"); reader = new BufferedReader(new InputStreamReader(in)); String line = ""; while ((line = reader.readLine()) != null) { content.append(line); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return content.

shell中等待其他程序执行完毕

有时候,该shell脚本需要等到另一个shell脚本 或 程序执行完毕之后,才开始执行。 提供一种方法: 查看 前序 脚本或程序 的进程是否已经执行结束: #如果有程序在make,则等待make结束 cnt=`ps -ef|grep "make"|grep "all"|grep -v grep|grep -v vi|wc -l` echo $cnt do while [ $cnt -nq 0 ] then cnt=`ps -ef|grep "make"|grep "all"|grep -v grep|grep -v vi|wc -l` echo $cnt sleep 5 done #如果前序 脚本或程序 正在执行,则等待5s count=`ps -ef|grep shell.sh|grep -v grep|grep -v vi|wc -l` echo $count do while [ $count-nq 0 ] then count=`ps -ef|grep shell.sh|grep -v grep|grep -v vi|wc -l` echo $count sleep 5 done #这下面可以写 要执行的 后续shell了

memset结构体初始化

memset可以方便的清空一个结构类型的变量或数组。 如: struct sample_struct { char csName[16]; int iSeq; int iType; }; 对于变量 struct sample_strcut stTest; 一般情况下,清空stTest的方法: stTest.csName[0]='\0'; stTest.iSeq=0; stTest.iType=0; 用memset就非常方便: memset(&stTest,0,sizeof(struct sample_struct)); 如果是数组: struct sample_struct TEST[10]; 则 memset(TEST,0,sizeof(struct sample_struct)*10);

经典排序算法(4)——折半插入排序算法详解

折半插入排序(Binary Insertion Sort)是一种插入排序算法,通过不断地将数据元素插入到合适的位置进行排序,在寻找插入点时采用了折半查找。 一、算法基本思想 (1)基本思想 折半插入排序的基本思想是:顺序地把待排序的序列中的各个元素按其关键字的大小,通过折半查找插入到已排序的序列的适当位置。 (2)运行过程 直接插入排序的运作如下: 1、将待排序序列的第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 2、从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置,在查找元素的适当位置时,采用了折半查找方法。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) (3)示例 二、算法实现(核心代码) C++实现: void binary_insertion_sort(int arr[], int len) { int i, j, temp, m, low, high; for (i = 1; i < len; i++) { temp = arr[i]; low = 0; high = i-1; while (low <= high) { m = (low +high) / 2; if(arr[m] > temp) high = m-1; else low = m+1; } } for (j = i-1; j>=high+1; j--) arr[j+1] = arr[j]; arr[j+1] = temp; } Java实现:

R基础入门教程

由于一个项目原因,需要用到R对数据进行回归分析和数据挖掘,因此花半天时间对R进行了一个基础的学习。这是之前整理的网易云课程上的一个视频教程中整理的。 这里贴出来,也提供给源代码下载地址(http://pan.baidu.com/s/1c1mV0Xy),方便大家直接在RStudio中执行测试,也方便自己和大家在学习过程中对基本的指令的查询。 我刚发现,有可能第一次打开会出现乱码。这时候在RStudio中选择tools->global options->code->saving里面将text encoding设置为UTF-8就好啦~ 安装RStudio之前必须先安装R,安装包下载地址给分享给大家。 R安装包:http://pan.baidu.com/s/1bnYK2g3 RStudio安装包:http://pan.baidu.com/s/1nu0kvVj 照着敲一遍,包你入门啦~不要偷懒!!不想往下看的话,就去下载上面给出链接的源代码tutorial.R文件哦。 #########################R learning############## ###1.R introduction #### #语言历史和特点 #1.1 R语言历史#### #R是S语言的一种实现。S语言是由AT&T贝尔实验室开发的一种用来进行数据探索、 #统计分析、作图的解释型语言。最初S语言的实现版本主要是S-PLUS. #S-PLUS是一个商业软件,它基于S语言,并由MathSoft公司的统计科学部进一步完善。 #后来Auckland大学的Robert Gentleman和Ross Ihaka及其他志愿人员开发了一个R系统 #R的使用与S-PLUS有很多类似之处,两个软件有一定的兼容性 #1.2 R的特点#### #1.有效地数据处理和保存机制 #2.拥有一整套数组和矩阵的操作运算符 #3.一系列连贯而又完整的数据分析中间工具 #4.图形统计可以对数据直接进行分析和显示,可用于多种图形设备。 #5.一种相当完善、简洁和高效的程序设计语言。包括条件语句、循环语句、用户自定义的递归函数以及输入输出接口。 #6.R语言是彻底面向对象的统计编程语言 #7.R语言和其他编程语言、数据库之间有很好的接口 #8.R语言是自由软件,可以放心大胆地使用,但其功能却不必任何其他同类软件差 #9.R语言具有丰富的网上资源 ###2. Rstudio和R的基本操作#### #2.1查看R语言自带的数据集 data() #直接输入数据集的名称,查看数据 CO2 #2.2快捷键 #Ctrl+Enter: #Ctrl+L: #Ctrl+Shift+S: #Ctrl+1: #Ctrl+2: #Ctrl+D: #2.3查看数据集的前6行#### head(CO2) #查看数据集的最后6行 tail(CO2) #2.4安装包(可以通过命令或者图形界面来咱安装)#### installed.packages("ggplot2") #加载包 library(ggplot2) #2.5创建向量和矩阵以及对它们的基本操作#### x1 <- c(1,2,3,4,5,6) x2 <- c(2,4,6,8,10,12) length(x1) mode(x1) class(x1) rbind(x1,x2) #行联合 cbind(x1, x2) #列联合

GBD调试简介

GDB 调试简介 一般来说,GBD帮助我们做下述四种事情: 1. 启动我们的程序(可以向我们的程序传递参数等); 2. 调试我们的程序,在指定位置停止(即,设置断点); 3. 程序停止时,检查程序发生了那些事情(如,查看函数调用栈); 4. 动态改变程序的执行环境(如,设置一个变量的值)。 从本质上说,所有调试工具提供的功能是一样的,只是提供给程序员的接口(使用方法)略有不同。 1. 命令简介 list : 简写l 列出当前源码,“+”和“-”分别表示像前、向后列出源码。 break :简写b 设置断点。可以用 “info break”查看断点信息。 next :简写n 单条语句执行。 continue :简写c 继续程序执行,遇到断点停止,否则执行到程序结束。 print : 简写 p 打印变量的值。 backtrace: 简写bt 查看函数堆栈。 finish : 退出函数。

Mac下生成CSR(.certSigningRequest)文件

当在苹果开发者中心生成证书的时候需要一个CSR(certificateSigningRequest)文件。 打开钥匙串访问工具,在钥匙串访问下拉菜单选中证书助理 --> 从证书颁发机构请求证书; 输入appId邮件地址、名称,选择存储到磁盘 步骤1: 步骤2: 步骤3:这里选取保存的位置是桌面,也可以选择自己喜欢的位置保存 这样就生成了一个CSR文件:

自我反思

我觉得我真的应该好好反思一下了。 我发现我做事情的态度极其不对。一开始总是抱着马马虎虎的态度混着,在外人看来貌似不错。其实心里明白,并没有真的用心,一切都是将就。一开始浑浑噩噩,然后有一天觉醒,开始恶补以前的坑。从小到大都是这样循环。我不知道自己是怎么回事。我想做一个认真优秀的女生,可每次当我反应过来的时候都有些晚了,那些美好的时间和光阴,我最该努力拼搏的时候都过去了。我觉得我错过了很多。在这一点上,我很不喜欢自己。 我真的希望改变,不要再继续这样。从一开始你就抱着一颗坚定的决心去努力,你要做一个优质的人。现在已经21岁了,我不想再重蹈覆辙。不想再浪费我的时间。希望从此刻起,对得起每一分钟。

关于YES、NO和TRUE、FLASE的区别

一般编程我们都默认非零值就是TRUE,为零时FALSE。 那么在Objective-C中,又出现了YES、NO。咋回事呢。是酱紫滴,OC中用一个字节,即8位来表示BOOL值,也就是取一个数的低八位。那么对于8960这个数,它明显是非零数字,但是,但是!它的低八位都是零,所以它是NO。 注意一点啊,我这里说它是YES、NO是指,你在赋值给一个BOOL型数据时的值。 比如BOOL a = 8960; 那么在判断if(a)的时候,他表现出来的特征就是NO。 或者if(a == YES)也是NO。 但是如果你这样if(8960)它依旧是YES。 但是bool a = 8960; if(a == YES)它是真的。。。 就是这么简单。自己好好寻思去吧。 (我要吐槽,,那个MarkDown有bug啊!!!!!!!!!再也不想用了!!!)

java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析

java面试中经常被问到list常用的类以及内部实现机制,平时开发也经常用到list集合类,因此做一个源码级别的分析和比较之间的差异。 首先看一下List接口的的继承关系: list接口继承Collection接口,Collection接口继承Iterable接口。 Iterable接口定义的方法: public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator(); } Collection接口中定义的方法: package java.util; public interface Collection<E> extends Iterable<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?

selenium2 java版

--加载驱动 System.out.println("开始web自动化!!"); System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); // System.setProperty("webdriver.chrome.driver","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"); --火狐浏览器 System.setProperty("webdriver.firefox.bin","D:\\dailyTool\\Mozilla Firefox\\firefox.exe"); --使用浏览器默认配置 // ProfilesIni pi = new ProfilesIni(); // FirefoxProfile profile = pi.getProfile("default"); FirefoxProfile profile = new FirefoxProfile(); driver = new FirefoxDriver(profile); driver.get("http://www.jd.com/"); driver.findElement(By.linkText("你好,请登录")).click(); // driver.findElement(By.id("loginname")).click(); 给输入框设置数据XXX driver.findElement(By.id("loginname")).sendKeys("XXX"); // driver.findElement(By.id("nloginpwd")).click(); driver.findElement(By.id("nloginpwd")).sendKeys(""); driver.findElement(By.id("loginsubmit")).click(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("这里是之前的windows:"+driver.getWindowHandle()); driver.findElement(By.linkText("我的订单")).click(); --注意这里,这里是跳转新的链接,需要判断需要操作的界面,然后switchTo Set<String> handles = driver.getWindowHandles(); WebDriver driver4 = null; int count = 0; for (String s : handles) { if(count == 1){ System.

Qt学习之QWizard向导界面

QWizard类提供了一个向导对话框的框架。 向导就是包含一组顺序的对话框页面的特定类型的输入对话框。向导的目的是让用户一步一步地完成一个过程。向导对于复杂或者偶尔发生的并且人们发现它很难学会或者执行的任务很有用处。 自己根据文档完成了一个小的例子,以备不时之需。 #include "mywizard.h" MyWizard::MyWizard(QWidget *parent) : QWizard(parent) { /*setOption( QWizard::NoBackButtonOnStartPage ); setOption( QWizard::NoBackButtonOnLastPage ); setOption( QWizard::NoCancelButton );*/ this->setOption( QWizard::NoBackButtonOnStartPage );//设置第一页没有上一步的按钮 this->setWizardStyle( QWizard::ModernStyle );//设置上一步下一步等按钮的显示格式 this->addPage(createFirstPage());//添加自己写好的QWizardPage页面 this->addPage(createSecondPage()); this->addPage(createThirdPage()); } QWizardPage *MyWizard::createFirstPage() { QWizardPage *firstPage = new QWizardPage; firstPage->setTitle(tr("第一步"));//设置第一个QWizardPage QLabel *picLabel = new QLabel; picLabel->setPixmap(QPixmap(":/image/first.jpg")); QHBoxLayout *firstLayout = new QHBoxLayout; firstLayout->addWidget(picLabel); firstPage->setLayout(firstLayout); firstPage->setButtonText(QWizard::BackButton,"上一步"); firstPage->setButtonText(QWizard::NextButton,"下一步");//为next设置一个中文的名字 firstPage->setButtonText(QWizard::CancelButton,"取消"); firstPage->setButtonText(QWizard::FinishButton,"完成"); return firstPage; } QWizardPage *MyWizard::createSecondPage() { QWizardPage *secondPage = new QWizardPage; secondPage->setTitle(tr("第二步")); QLabel *picLabel = new QLabel; picLabel->setPixmap(QPixmap("

DICOM基础知识--有用资料

DICOM 文件可以大致分为两部分: 一部分:与 图像 相关 的 元 信息 ,包括患者信息,检查信息,序列信息,图像信息等等。 另一部分:图像的像素数据。 在解析DICOM文件中的像素数据的时候,我们先需要读取以下图像相关信息: 以下 是 某个CT影像中的图像信息示例: (0028,0002) Samples per Pixel VR: US Length: 2 Value: 1 (0028,0004) Photometric Interpretation VR: CS Length: 12 Value: MONOCHROME2 (0028,0010) Rows VR: US Length: 2 Value: 512 (0028,0011) Columns VR: US Length: 2 Value: 512 (0028,0030) Pixel Spacing VR: DS Length: 22 Value: 0.48828125\0.48828125 (0028,0100) Bits Allocated VR: US Length: 2 Value: 16 (0028,0101) Bits Stored VR: US Length: 2 Value: 12 (0028,0102) High Bit VR: US Length: 2 Value: 11 (0028,0103) Pixel Representation VR: US Length: 2 Value: 0 (0028,1050) Window Center VR: DS Length: 12 Value: 00100\00100 (0028,1051) Window Width VR: DS Length: 12 Value: 00500\00500 (0028,1052) Rescale Intercept VR: DS Length: 6 Value: -1000 (0028,1053) Rescale Slope VR: DS Length: 2 Value: 1 (0028,2110) Lossy Image Compression VR: CS Length: 2 Value: 01 (0028,2112) Lossy Image Compression Ratio VR: DS Length: 8 Value: 6.

修改HttpServletRequest的中的参数值

利用SpringMVC上传文件,方法A @RequestMapping(value = "/saveJobInfoFromFile", method = {RequestMethod.POST}) @ResponseBody public ReturnInfo saveJobInfoFromFile(HttpServletRequest request,HttpServletResponse response);中,我将要循环调用下面的方法B: @RequestMapping(value = "/saveJobInfo", method = {RequestMethod.POST}) @ResponseBody public ReturnInfo saveJobInfo(HttpServletRequest request,HttpServletResponse response, String jobJson); 由于方法A中的request需要获取上传的文件,但是这个文件又不能传递给方法B(会有干扰),所以我需要对request的参数进行修改。代码如下: // 创建一个通用的多部分解析器 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(servletContext); // 判断 request 是否有文件上传,即多部分请求 if (multipartResolver.isMultipart(request)) { // 转换成多部分request MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; // 取得request中的所有文件名 Iterator<String> iter = multiRequest.getFileNames(); while (iter.hasNext()) { // 取得上传文件 MultipartFile file = multiRequest.getFile(iter.next()); if (file != null) { FileUtils.

C# 邮件发送 实现类

using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Linq; using System.Net.Mail; using System.Net.Mime; using System.Text; namespace IntOA.Common { public class EmailSender { private MailMessage mMailMessage; //主要处理发送邮件的内容(如:收发人地址、标题、主体、图片等等) private SmtpClient mSmtpClient; //主要处理用smtp方式发送此邮件的配置信息(如:邮件服务器、发送端口号、验证方式等等) private bool mEnableSsl; //是否对邮件内容进行socket层加密传输 private bool mEnablePwdAuthentication; //是否对发件人邮箱进行密码验证 private static string _mSenderPort = null; //发送邮件所用的端口号(htmp协议默认为25) public static string mSenderPort { get { if (_mSenderPort == null) { _mSenderPort = ConfigurationManager.AppSettings["mSenderPort"]; } return _mSenderPort; } } private static string _mSenderServerHost = null; //发件箱的邮件服务器地址(IP形式或字符串形式均可) public static string mSenderServerHost { get { if (_mSenderServerHost == null) { _mSenderServerHost = ConfigurationManager.

Lua -- 闭包

闭包的概念 在Lua中,闭包(closure)是由一个函数和该函数会访问到的非局部变量(或者是upvalue)组成的,其中非局部变量(non-local variable)是指不是在局部作用范围内定义的一个变量,但同时又不是一个全局变量,主要应用在嵌套函数和匿名函数里,因此若一个闭包没有会访问的非局部变量,那么它就是通常说的函数。也就是说,在Lua中,函数是闭包一种特殊情况。另外在Lua的C API中,所有关于Lua中的函数的核心API都是以closure(而非function)来命名的,也可视为这一观点的延续。在Lua中,函数是一种第一类型值(First-Class Value),它们具有特定的词法域(Lexical Scoping)。 第一类型值表示函数与其他传统类型的值(例如数字和字符串类型)具有相同的权利。即函数可以存储在变量或table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值,可以在运行期间被创建。在Lua中,函数与所有其他的值是一样都是匿名的,即他们没有名称。当讨论一个函数时(例如print),实质上在讨论一个持有某个函数的变量。比如: function foo(x) print(x) end 实质是等价于 foo = function (x) print(x) end 因此一个函数定义实质就是一条赋值语句,这条语句创建了一种类型为“函数”的值,并赋值给一个变量。可以将表达式function (x) end 视为一种函数构造式,就像table的构造式{}一样。 值得一提的是,C语言里面函数不能在运行期被创建,因此不是第一类值,不过有时他们被称为第二类值,原因是他们可以通过函数指针实现某些特性,比如常常显现的回调函数的影子。 词法域是指一个函数可以嵌套在另一个函数中,内部的函数可以访问外部函数的变量。比如: function f1(n) --函数参数n也是局部变量 local function f2() print(n) --引用外部函数的局部变量 end return f2 end g1 = f1(2015) g1() -- 打印出2015 g2 = f1(2016) g2() -- 打印出2016 注意这里的g1和g2的函数体相同(都是f1的内嵌函数f2的函数体),但打印值不同。这是因为创建这两个闭包时,他们都拥有局部变量n的独立实例。事实上,Lua编译一个函数时,会为他生成一个原型(prototype),其中包含了函数体对应的虚拟机指令、函数用到的常量值(数,文本字符串等等)和一些调试信息。在运行时,每当Lua执行一个形如function…end 这样的表达式时,他就会创建一个新的数据对象,其中包含了相应函数原型的引用及一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。由此可见,函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。g1和g2的值严格来说不是函数而是闭包,并且是两个不相同的闭包,而每个闭包能保有自己的upvalue值,所以g1和g2打印出的结果当然就不相同了。 这里的函数f2可以访问参数n,而n是外部函数f1的局部变量。在f2中,变量n即不是全局变量也不是局部变量,将其称为一个非局部变量(non-local variable)或upvalue。upvalue实际指的是变量而不是值,这些变量可以在内部函数之间共享,即upvalue提供一种闭包之间共享数据的方法,比如: function Create(n) local function foo1() print(n) end local function foo2() n = n + 10 end return foo1,foo2 end f1,f2 = Create(2015) f1() -- 打印2015 f2() f1() -- 打印2025 f2() f1() -- 打印2035 注意上面的例子中,闭包f1和f2共享同一个upvalue了,这是因为当Lua发现两个闭包的upvalue指向的是当前堆栈上的相同变量时,会聪明地只生成一个拷贝,然后让这两个闭包共享该拷贝,这样任一个闭包对该upvalue进行修改都会被另一个探知。

实习生刚入职 两周总结

很不幸,稻草又要一个人奋斗了! 在这之前,扬扬还是把这两周的实习工作总结跟小伙伴们分享一下吧! 到公司(一个工作室)的第一件事,配置环境吧!给你一些网上的教程资料,前几天就是自己了,几乎不怎么搭理你的! 我进去这家用的是Quick3.3,开发工具用的是Sublime Text3.0,打包用的是Esplice安装adt插件,sdk,jdk什么的网上有,我们这里也给了,就是版本不一样!(折腾了两天)本人也算是职场小白了,还没毕业!大神们不要笑话俺。 环境搭建好以后,开始着手lua的基础知识的巩固和Quick 3.3开发的基础学习,这些在泰然网和cocos2d-x官网都可以找的到! 入职后的第四天上午,开始给一些简单的界面,让你自己去pin。也就是,那些基础的东西,你有三天的时间去回顾!(有些不知所措!),当时学的是cocos2d-x,但是lua用起来还是比较方便的,一些东西都是大神们封装好的!当然了我们用的一些东西也是老板(也就是主程,就我和老板俩人儿是游戏程序)封装的。 第五天就开始让我实现一个项目中的一系列小精灵走动和拖拽的功能了!(大神勿喷!这对于我来说也是有一定的难度的,一方面是公司自己的那一套,要去了解,另一方面过完春节感觉手生的很,一些逻辑性的东西也想不到!) 当接触到这个功能第五天的时候,老板要求的那些功能已经基本上实现了,但是又说我写的一些代码太冗余了!还有,公司面试了一个有经验的老手,我被无情的替换掉了! 扬扬的心情有些失落,如果要求有工作经验的,为什么当初还要招我这个还没毕业的实习生呢!哎呀,难道是自己学的东西连实习生的资格都没有?算了,这周把以前的代码回顾一下,多敲几个小demo,下周又要安下心来开始面试了! 愈挫愈勇!加油,在通往程序道路中奔波的骚年们!

C#中keybd_event 用法 模拟键盘鼠标按键 打印

Windows提供了一个模拟键盘API函数Keybd_event(),使用该函数可以相应的屏蔽键盘的动作。Keybd_event()函数能触发一个按键事件,也就是说会产生一个WM_KEYDOWN或WM_KEYUP消息。该函数原型如下: VOID keybd_event( BYTE bVk, // virtual-key code BYTE bScan, // hardware scan code DWORD dwFlags, // flags specifying various function options DWORD dwExtraInfo // additional data associated with keystroke ); 从上述原型可以看出,Keybd_event()共有四个参数。 第一个为按键的虚拟键值,如回车键为vk_return,tab键为vk_tab。 第二个参数为扫描码,一般不用设置,用0代替就行。 第三个参数为选项标志,如果为keydown则置0即可,如果为keyup则设成"KEYEVENTF_KEYUP" 或是 "0x2"。 第四个参数一般也是置0即可。'A'的虚拟键值为65,所以可以用如下代码实现模拟按下'A'键, keybd_event(65,0,0,0); keybd_event(65,0,KEYEVENTF_KEYUP,0); Windows还提供了一个API函数mouse_event,可以模拟一次鼠标事件,比如左键单击、双击和右键单击等。 mouse_event函数原型如下: VOID mouse_event( DWORD dwFlags, // flags specifying various motion/click variants DWORD dx, // horizontal mouse position or position change DWORD dy, // vertical mouse position or position change

Logistic Regression 之基础知识准备

转载:http://www.cnblogs.com/daniel-D/ 0. 前言 这学期 Pattern Recognition 课程的 project 之一是手写数字识别,之二是做一个网站验证码的识别(鸭梨不小哇)。面包要一口一口吃,先尝试把模式识别的经典问题——手写数字识别做出来吧。这系列博客参考deep learning tutorial ,记录下用以下三种方法的实现过程: Logistic Regression - using Theano for something simpleMultilayer perceptron - introduction to layerDeep Convolutional Network - a simplified version of LeNet5 目的在于一方面从理论上帮自己理顺思路,另一方面作为课程最后一课 presentation 的材料。这三种方法从易到难,准确率也由低到高,我们先从简单的入手。 1. Binomial logistic regression model 尽管线性分类器方法足够简单并且使用广泛,但是线性模型对于输出的 y 没有界限,y 可以取任意大或者任意小(负数)的值,对于某些问题来说不够 adequate, 比如我们想得到 0 到 1 之间的 probability 输出,这时候就要用到比 linear regression 更加强大的 logistic regression 了。 y = w • x 直觉上,一个线性模型的输出值 y 越大,这个事件 P(Y=1|x) 发生的概率就越大。 另一方面,我们可以用事件的几率(odds)来表示事件发生与不发生的比值,假设发生的概率是 p ,那么发生的几率(odds)是 p/(1-p) , odds 的值域是 0 到正无穷,几率越大,发生的可能性越大。将我们的直觉与几率联系起来的就是下面这个(log odds)或者是 logit 函数 (有点牵强 - -!

mySQL中索引index详解

索引 mysql <wbr>索引(index) 注意: 1、不要过度索引 2、索引条件列(where后面最频繁的条件列) 3、尽量索引散列值,过于集中的值不要索引。 索引类型 1、普通索引(index):仅仅是加快查询速度 2、唯一索引(unique index):行上的值不能重复 3、主键索引(primary key):主键不能索引 主键索引必定是唯一的,唯一索引不一定是主键, 一张表上只能一个主键,可以有一个或者多个唯一索引。 4、全文索引(fulltext index):在mysql 默认情况下对于中文作用不大。 查看 一张表上的索引 show index from 表名(/G可以横着显示) 索引不知道名称默认以索引的列名作索引 建立索引 alter table 表名add index/unique/fulltext [索引名](列名) [索引名]可以不写 ,不写默认与列名相同。 alter table 表名add primary key (列名) 创建索引示例: 为 tel列 创建普通索引 为email列 添加唯一索引 为intro列添加全文索引 为id列添加主键 删除索引 alter table drop index 索引名 示例: 删除email(唯一)索引 删除主键索引 全文索引使用 查看匹配度 select 列名, match (索引) against (‘ 索引词’) from表名; 新发现 as 支持 汉字

gstreamer插件调用ffmpeg 详解

Gstreamer调用FFMPEG解析 ----Gstreamer 是如何操作ffmpeg的,以及ffmpeg是如何demux的(AVI 容器格式为例) AVI容器格式较为简单,所以这里用AVI为例,分析gstreamer如何通过ffmpeg来对多媒体文件demux,获得原始数据流。 1. Gstreamer,ffmpeg, OMX框架关系 图一,框架 Gstreamer通过gst-ffmpeg插件,来管理文件container的demux,gst-ffmpeg通过ffmpeg的libavformat来具体实现对各种文件容器的demux。 1, 主循环建立在gst-ffmpeg插件中, gst_ffmpegdemux_loop 2,gst-ffmpeg调用ffmpeg的API av_read_frame , 来读取一个完整的帧数据 3,ffmpeg 在av_read_frame内部,完成demux工作 4,文件系统的读操作,由ffmpeg调用gstfilesrc插件的read来实现 5,一帧数据读出以后,由gst-ffmpeg利用gstreamer的pad push 机制,送到gst-OMX 6, pad push 到GST-OMX后,立即返回。OMX实质上采用异步的方式,送到解码器 2. Gstreamer调用Ffmpeg的调用链 下面图二在图一的基础上展示了各插件各模块之间的具体调用关系,就不用语言叙述了,对着代码看吧。。。 图二,各模块调用链 3. Avi容器格式介绍 AVI格式是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,现在已被Windows 95/98、OS/2等多数操作系统直接支持。AVI格式允许视频和音频交错在一起同步播放,支持256色和RLE压缩,但AVI文件并未限定压缩标准,因此,AVI文件格式只是作为控制界面上的标准,不具有兼容性,用不同压缩算法生成的AVI文件,必须使用相应的解压缩算法才能播放出来。常用的AVI播放驱动程序,主要是Microsoft Video for Windows或Windows 95/98中的Video 1,以及Intel公司的Indeo Video。 在介绍AVI文件前,我们要先来看看RIFF文件结构。AVI文件采用的是RIFF文件结构方式,RIFF(Resource Interchange File Format,资源互换文件格式)是微软公司定义的一种用于管理windows环境中多媒体数据的文件格式,波形音频wave,MIDI和数字视频AVI都采用这种格式存储。构造RIFF文件的基本单元叫做数据块(Chunk),每个数据块包含3个部分, 1、4字节的数据块标记(或者叫做数据块的ID) 2、数据块的大小 3、数据 整个RIFF文件可以看成一个数据块,其数据块ID为RIFF,称为RIFF块。一个RIFF文件中只允许存在一个RIFF块。RIFF块中包含一系列的子块,其中有一种字块的ID为"LIST",称为LIST,LIST块中可以再包含一系列的子块,但除了LIST块外的其他所有的子块都不能再包含子块。 RIFF和LIST块分别比普通的数据块多一个被称为形式类型(Form Type)和列表类型(List Type)的数据域,其组成如下: 1、4字节的数据块标记(Chunk ID) 2、数据块的大小 3、4字节的形式类型或者列表类型 4、数据 下面我们看看AVI文件的结构。AVI文件是目前使用的最复杂的RIFF文件,它能同时存储同步表现的音频视频数据。AVI的RIFF块的形式类型是AVI,它包含3个子块,如下所述: 1、信息块,一个ID为"hdrl"的LIST块,定义AVI文件的数据格式。 2、数据块,一个ID为 "movi"的LIST块,包含AVI的音视频序列数据。 3、索引块,ID为 "idxl"的子块,定义 "

查经 民数记3章 利未人

3章 利未人:1~4节,亚伦的儿子们;5~13节,利未人的职责;14~39,利未人男丁的统计;40~51节,利未人代替长子的地位。 本章记载了利未人被神呼召,代替以色列各家长子成为事奉神的人,利未人的宗族、人数、及各族负责的事务。这件事灵意上的含义是,事奉神的人,是神凭着祂自己的主权拣选呼召出来的。若人凭着自己的主观意志和能力事奉神,既是对神主权的不顺服,也不具备圣灵的恩赐和智慧,不能正确地照着神旨意来事奉。 1~4节,摩西是神拣选的先知,神藉着摩西带领以色列百姓。摩西是以色列民族信仰的领袖,而亚伦是神拣选的、在会幕事奉神的祭司长的代表。他们各自在职份上的差异,并不是他们人格的差异,而是神凭着祂自己主权、建立神政国度时拣选、膏立的工人,都是被神使用的器皿。今天教会的事奉也应该如此有秩序。 虽然提到说“亚伦和摩西的后代”,但是后面记录的是亚伦的儿子,没有记录摩西的儿子。这是因为神没有吩咐。摩西虽然是圣经的记录者,但也没有凭着他自己的意思记下自己的儿子。虽然身为以色列领袖的儿子,但是摩西的儿子们没有被神呼召,所以依然是普通的利未人。这里看到的是摩西对神完全的谦卑顺服。 亚伦的两个儿子拿答、亚比户在任祭司职份时,将凡火献在神面前,而被神降下火烧灭(利10:1~2)。“凡火”指的是:不是照着神的话语所吩咐的火。凡火的灵意指的是,凡是按自己的意志,而不是按神的旨意事奉神的一切言行。再华丽、被人拥戴和支持的事奉,如果无视神的主权和旨意,神是绝对不会悦纳的。 所以,事奉神,必须首先有一颗对神敬畏的心。何谓敬畏神?就是尊重祂的主权、相信祂的智慧、甘愿舍弃己意、照着神启示的话去遵行。并不是自己感觉敬畏神,就是敬畏神了,实际行事为人,依然照着自己想当然的意思。耶稣说听了神之道而遵行的人就是祂的亲属。其中隐含两个条件:1、听神之道;2、且遵行。 5~13节,利未人的职责是,根据神的命令、顺服亚伦的领导、作为祭司的协助者,帮助祭司献祭、办理帐幕的事、看守会幕的器具。但利未人不能做圣所和至圣所内的事,也不能进到燔祭坛前。祭司是分别为圣归给神,在圣所里直接事奉神的人。而利未人作为祭司的助手,归属于祭司,要服侍祭司,间接地事奉神。 神的百姓人格平等,不代表在事奉神的时候没有秩序。这个秩序是由神来确立的,并不是人可以凭着自己的意思随意安排的。每个神的百姓都应顺服神所定的秩序。亚伦和他的儿子作祭司,比起普通的以色列百姓,神赐给他们更大的权柄;但同时,也交托给他们更大的责任。所以神警示他们,要谨守自己祭司的职任。 没有被神呼召、没有被神膏立为祭司的人进到神的面前,必被治死。圣洁的神与罪不能同行,只有照神的话语被祂洁净的人才能进到祂的面前。对圣洁神没有敬畏之心、对自己的罪恶没有自惭形秽之心,认为自己有资格进到神面前的人,自取灭亡。永生神真是不能轻慢的!这是关于神之圣洁的事,也是关乎生死的事! 14~39节,利未人中只要满一个月的男丁就被数点。这跟以色列数点各支派20岁以上可以打仗的兵丁是不一样的。因为无论大小,神的百姓都有事奉神的责任。但是,作为神的军队争战,则需要生命成熟的人。在那时候,初生婴儿存活率较低,满了一个月后存活的可能就大了很多,所以新生儿的父母会在满月时庆祝。 利未人有三大支派:革顺、哥辖、米拉利。其中,革顺的子孙看守帐幕和罩棚,罩棚的盖与会幕的门帘以及院子的幔子、门帘和绳子;哥辖的子孙看守约柜等在至圣所和圣所以及院子中的器具;米拉利子孙看守帐幕的板柱子等。神照着祂的旨意将不同的事交给不同的人,让他们各司其职,各负所责,彼此搭配做主工。 其中神拣选以利亚撒作利未人众首领的领袖,鉴察那些看守圣所的人。神会赐下祂的仆人在现今教会:传道、牧师和教师,让他们用神的道教导神的百姓,照神的道鉴察保护教会。圣灵也会随己意分给各位圣徒各样属灵的恩赐,让圣徒在教会照着神的恩赐彼此服侍,连于元首基督,建立基督的身体,在爱里建立自己。 40~51节,神击杀埃及人的长子以拯救以色列百姓的逾越节事件里,保守了以色列百姓免受灾害,所以以色列百姓的长子是归属于神的。神拣选了利未人代替以色列百姓的长子,在会幕事奉祂,所以利未人的事奉也被称为长子的事奉。如今在教会里的事奉,也被称为利未人的事奉,更多神的百姓是在生活里事奉神的。

通过el表达式配置使jsp直接调用java静态方法

创建java静态方法 package demo; import java.util.Map; /** * Created by Administrator on 2016/3/6. */ public class Demo { public static String demo(){ String str = "11111111111"; return str; } } 在WEB-INF目录下创建.tld文件,我这里是sdk.tld <?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.2</tlib-version> <short-name>sdk</short-name> <function> <name>demo</name> <function-class>demo.Demo</function-class> <function-signature>java.lang.String demo()</function-signature> </function> </taglib> 3.在web.xml中配置sdk.tld <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <jsp-config> <taglib> <taglib-uri>Demo</taglib-uri> <taglib-location>/WEB-INF/sdk.tld</taglib-location> </taglib> </jsp-config> </web-app> 4.编写jsp文件,并且引入sdk.tld <%-- Created by IntelliJ IDEA.

深度优先遍历的栈实现

——PickingupJewels 捡珠宝是典型的需要回溯的深度优先遍历,它要求找出能获得最多珠宝的路径,并且将该路径输出。 这个题比较难的两点是怎么不走环路和怎么回溯。回溯相对简单一点,就是出栈以后,你要将它置为未访问过,不用担心重复走它,因为还有方向控制前进的方向。 而对于环路,一开始想得很苦恼,没明白,多设了很多条件,后来还是在老大的帮助下,想通了其实不重复进栈就不会走环路,因为栈内的点是刚走过的路。 void DFS(Node* start, Node* end) { int dx,dy; int i; Node* n = start; n->dir = 0; // 入栈则将方向置为0 push(start); // 将起始点入栈 jewels_num = 0; // 珠宝数 Node* tmp; // 取栈顶元素 if(start->value == 2) jewels_num++; //如果起点是珠宝,则珠宝数++ if(end->value == 2) jewels_num++; //如果终点是珠宝,则珠宝数++ while(!isEmpty()) { // 如果栈不为空 tmp = getTop(); // 取栈顶节点 for(i=tmp->dir; i<4; i++) { // 将方向置为栈顶元素的方向 tmp->dir++; // 栈顶元素方向++,表明走过一个方向(进栈为0,当dir为4时则表明该点4个方向已遍历) dx = tmp->x + DIR[i][0]; dy = tmp->y + DIR[i][1]; if(dx == end->x && dy == end->y) { // 如找到终点 if(jewels_num>Answer) { // 判断当前路径找的珠宝数是否比已保存的数要多 Answer = jewels_num; // 始终保存最大的珠宝数 saveCurrentPath(); // 并存储该路径 } #ifdef TEST cout<<"

mybatis中使用log4j打印sql语句不起作用问题

最近项目中添加新的jar包后,突然发现控制台中mybatis无法正常打印sql语句,造成很多调试过程中的麻烦。在网上搜索相关的问题,有一篇文章点击打开链接讲的是这个问题,可能的原因是某些jar包中使用的是slf4j,而不支持log4j,从而影响了正常的log4j使用,需要添加log4j与slf4j之间的转换jar包。于是我在项目中添加了slf4j-log4j12-1.7.18.jar这个jar包,重试问题果然解决了。 注意:log4j12中的12是log4j的版本号,即log4j 1.2版本。

mysql, mariaDB 分库分表设计草案及相关笔记

A.分库分表方法: 1. 哈希法, 就是俗称取模法 2. 一致性哈希, 是对方法1的改进。 3. range区间法 4. 查表法 总结: 以上4种方法都需要一个或多个分库分表主键,通过主键并按分库库表规则计算 当前数据库操作对应到哪台具体数据库和表。 B. 设计概念 1. DBAtom : { ip, port ,user, pwd, factor, enable} 存储到map中, ip+port as map key. 这是一个扁平的map, 所有的master , slave一视同仁, 都放到这个map中,供集中查询. var DBAtomRepository [string] DBAtom //ip + port as map key. 2. DBGroup : {master: DBAtomname, slave: [DBAtomname...]} a slice,注意一个DBGroup中只充许有一个Master,即第一个为Master,其它皆为Slave; 一个DBGroup就是对应一个mysql master-slave集群; 存储到map中,value为数组; 当前集群规定皆是 one Master to 2 Slave. var DBGroupRepository [string] DBGroup //uuid as map key, 可以配置中心统一生成,以保证唯一.

CentOS服务器的目录映射为Windows磁盘驱动器的方法(安装samba)

一、安装Samba前准备 1、使用Samba服务器需要防火墙开放以下端口 UDP 137 UDP 138 TCP 139 TCP 445 vi /etc/sysconfig/iptables #配置防火墙端口 -A INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 137 -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 138 -j ACCEPT

SFTP 实践

FTP是文件传输协议。如果你想把文件和人共享,最便捷的方式莫过于把文件上传到FTP服务器上,其他人通过FTP客户端程序来下载所需要的文件。 FTP进行文件传输需要通过端口进行。一般所需端口为: 1. 控制链路—TCP端口21。控制器端。用于发送指令给服务器以及等待服务器响应。 2. 数据链路---TCP端口20。数据传输端口。用来建立数据传输通道的。主要用来从客户向服务器发送一个文件、从服务器向客户发送一个文件、从服务器向客户发送文件或目录列表。 FTP为了适应不同的网络环境,支持主动连接和被动连接两种模式。这两种模式都主要针对数据链路进行的,跟控制链路无关。 FTP的安全隐患: 一、FTP服务器软件漏洞。 二、明文口令。 三、FTP旗标。 四、通过FTP服务器进行端口扫描。 五、数据劫持。 FTP的安全策略: 一、使用较比安全的系统和FTP服务软件。 二、使用密文传输用户名和口令。 三、更改服务软件的旗标。 四、加强协议安全性。 SFTP是Secure File Transfer Protocol的缩写,是安全文件传送协议。可以为传输文件提供一种安全的加密方法。跟ftp几乎语法功能一样。 SFTP是SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。它本身没有单独的守护进程,必须使用sshd守护进程来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以使用SFTP是十分安全的。但由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多。在对网络安全性要求更高时,代替FTP使用。 <dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.53</version> </dependency> 注意事项:Session 也需要关闭,否则会造成sshd进程过多,需要重启ssh package com.xxx.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.commons.lang.exception.ExceptionUtils; import org.springframework.util.CollectionUtils; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.

陌陌推出点赞匹配功能,动了谁的蛋糕?

陌陌推出点赞匹配功能,动了谁的蛋糕?(转) 文/判官 2016年3月1日,陌陌发布的6.6版,最主要的变化是加入了点赞匹配功能——点点。什么是点赞匹配呢?国内最早把这个功能做起来的是探探。通俗的说,就是针对异性用户的照片,向右滑动照片表示喜欢,向左滑动照片表示不喜欢。若对方也以同样的操作对你表示了喜欢,则软件给出提示,两人可直接沟通。 滑动点赞匹配这个功能,源于美国的Tinder。这款产品2012年底发布以来,在美国校园热度不减,获得了中意简单粗暴的年轻人们的热爱。缘分匹配这件事情从未如此轻松,只要动动手指,连聊天都不用就可以找到彼此中意的人。当然,主要还是拼颜值。 Tinder发布后,照例在中国涌现出一众模仿者,其中探探以其母公司——街拍产品P1旗下优质的年轻高颜值用户储备脱颖而出,2015年上半年坐定了同类产品老大地位,并顺利融资。然而之后的探探在产品迭代节奏上非常保守,主要的新增功能是标签和兴趣爱好,以及增加了朋友圈和匿名表白。但在笔者看来,最为重大的改变是允许用户在资料里填写自己的微信号。为何说这一点最为重大,后文会解释。 至于陌陌的前世今生,大家都很熟悉,这里也就不多介绍。陌陌在6.0之后的演进节奏趋缓,甚至出现了把附近的人折叠进二级菜单又释放出来的迭代回滚。在陌陌现场悄悄蜕变成为陌陌直播之后,陌陌增加了聊天室、话题以及附近红包这样的功能,但从未像这次点赞匹配一样进行引导页推广和开放首屏入口,其重视程度不言而喻。 为何陌陌在这个时间节点增加了一个已经被别的产品玩烂的功能? 探探的处境 虎嗅作者“辩手李慕阳”的文章中曾经提出:社交产品的核心竞争力和差异化,在于底层匹配逻辑的创新,这一点笔者深以为意。当年陌陌的起家——LBS陌生人社交,也是这样一种创新。然而底层逻辑的差异化又谈何容易? 以探探为例,实际使用过程中,男性用户大都在不看屏幕的情况下连续右滑,看脸变成拼手气,赌的是提升数量提高命中率。出现这种情况的原因,并非因为国内用户更饥渴更功利,而是比起起母产品Tinder,探探缺乏一个最重要的立足基础——用户的真实性。 Tinder为代表的大多数国外社交产品,是基于Facebook的用户,而Facebook的实名制保证了用户profile和质量的可信度。因此国外产品可以放心地在“底层匹配逻辑的差异化”上做文章。但到了国内,营销账号和微商遍地走的情况下,新的社交产品实际上很容易被架空,失去可以依赖的优质用户(起码是真实用户)土壤,加上用户数对融资的重要性,用户的质量这一立足点很容易让位于用户数量。 这种情况下,看脸有什么意义?不如使劲右滑,瞎猫撞死耗子,碰到就是赚到。当然了,屏幕那一端也有拼命右滑屏幕的女用户,可惜的是她并不是性饥渴,可能只是个来吸粉的微商、酒托、小姐之类。 难道国内的社交产品就没有可依赖的基础环境吗? 大家会发现,其实微信充当了这一作用。由于微信具备了高频使用,高可信度(一台手机只能同时登录一个微信账户,个别安卓机支持双开多开除外),一定程度负担起了Facebook的作用,我们可以认为微信是国内社交产品中唯一可信赖的、用户真实度较高的平台。用微信作为可参考的profile,提高社交的可信度,其实也是用户的一种选择,于是“加个微信吧?”也成为了大多数用户线上线下结识陌生人之后的本能反应。于是探探允许用户在产品中预留微信联系信息,其实是一种正确的选择。 笔者在自己的出行社交产品“旅客”中采取了更极端的做法,即用户只能通过预留的微信或QQ联系,并不提供IM功能。这种设计的原因,在于微信实际上已经成为十年前的手机号,是社交产品必须接入的“水电气”。与其回避,不如善加利用,况且用户可以不再打开你的新应用,但不会不打开微信和QQ吧?利用微信和QQ的高活跃度保障新产品的活跃度,是这样设计的主要目的。 陌陌添加点赞匹配这个功能是否明智? 分析了探探的处境,我们回到主题,看看陌陌添加点赞匹配这个功能是否明智。应该说,在陌生人社交的产品中,陌陌的用户粘性在于:搭建了一个完整的用户生态,从陌生人的邂逅入手,提供IM->状态->群组->娱乐(直播,游戏,活动)->O2O服务。用户不需要离开陌陌就可以完成社交活动的闭环,在陌陌认识的人无需转移到微信,也可以保持体验良好的互动,而很多用户也确实在这样做。目前有很多陌生人社交产品也能提供这样的一揽子解决方案,但陌陌是此类产品中做得最早最大的,很多用户想认识陌生人的时候只会想到陌陌,这就是所谓的思维锚定效应,还是蛮有效的。 最后,在LBS的社交场景下,陌陌做到极致了,后来者难以超越,这是陌陌抓住的隐性刚需。至于显性刚需,正如陌陌所标榜的,你用陌陌因为你对这个世界有好奇心。这两点刚需的威力,大家可以感受一下。 其实说到这里,大家会发现,在陌生人社交领域,从“提供可信的profile参考系”这一点,陌陌可以替代微信的作用。固然在陌陌上也会出现索要微信号的行为,但大多数情况下,在陌陌认识的人,通过陌陌保持联系和互动,已经足够。换句话说,陌陌就是陌生人社交领域的微信。 于是,点赞匹配这件事,由陌陌来做,就显得理所应当。自身产品的可信度作为用户背书,又提供了完善的互动环境,这种情况下添加点赞匹配,效果就比较理想了。在这一点上,陌陌可以继续引入新的功能模块,为当前的用户提供更多的重构逻辑,提供更多的乐趣,这是陌陌得天独厚的优势。 至于微信,目前除了群组,还没有更多的用户重构模块。出于微信定位的保守和克制,以及微信的普及化,这项工作可以由外部产品和线下社交来担当。于是外部产品负责重构和重新匹配用户,微信负责基础沟通和个人信息沉淀,也算是各得其所。 最后总结一下 陌陌的这次迭代以及未来的类似迭代,受到影响的主要是两类产品: 一类是探探这样的主打单一功能但用户真实性架空的产品,可能需要在用户身份真实性上做做文章来扳回一城; 另一类是美丽约这种传统的陌生人付费社交产品,产品简直是一个匹配模块大杂烩。如果陌陌继续增加适用于SVIP用户的高门槛特权模块,就会动摇美丽约的立身基础。 如果可以顺利侵入这两类产品的用户场景,陌陌的用户基础和活跃度可得到进一步巩固。 判官,”旅客“App创始人,十年移动产品工作经验,曾从事手机及ROM行业,现在专注于社交产品。微博:@_判官_ 本文由 判官 授权 虎嗅网 发表,并经虎嗅网编辑。转载此文章须经作者同意,并请附上出处(虎嗅网)及本页链接。原文链接http://www.huxiu.com/article/140499/1.html

github上的提交数统计

之前在github上使用一直没有注意一个问题,就是我最近频繁的提交,但是github上没有显示我提交频繁程度。我明明每天都有提交,这个是什么原因? 于是我查阅了一下,github上对于贡献统计的要求,一般来说都有以下几点了: 1.fork是不能算的,你必须是你提交的这个项目中的成员 2.你提交的pull申请必须通过了才会算。 ...... 最后一条:你在github上的邮箱地址和你当前提交的邮箱地址必须一致,才会被算作有效统计。 原来如此,由于前段时间我修改了我留在github上的邮箱地址,而本地的github上的地址没有进行更新。所以导致最近的几个月的提交都是没有被统计的。 so,纠结自己在github上的提交次数迟迟没有更新的小伙伴们,可以检查一下地址哦。既然已经知道了原因,那么如何修正这个问题呢?下面给出方法。 github官网上给出了教程,如下图所示 具体修改的命令如下图所示:

ORACLE SPATIAL介绍

一、 ORACLE SPATIAL 简介 ORACLE SPATIAL 是Oracle 的支持GIS数据存储的空间数据处理系统,是 Oracle 数据库强大的核心特性,包含了用于存储矢量数据类型、栅格数据类型和持续拓扑数据的原生数据类型。ORACLE SPATIAL使得我们能够在一个多用户环境中部署地理信息系统(GIS),并且与其它企业数据有机结合起来,统一部署电子商务、政务。有了ORACLE SPATIAL 之后,即可用标准的 SQL 查询管理我们的空间数据。 二、 ORACLE SPATIAL 表结构简介 Oracle 支持自定义的数据类型,你可以用数组,结构体或者带有构造函数,功能函数的类来定义自己的对象类型。这样的对象类型可以用于属性列的数据类型,也可以用来创建对象表。而Oracle Spatial也正是基于此种特性所开发的一套空间数据处理系统。 Spatial 的自定义数据类型有很多,都在MDSYS方案下,经常使用的是SDO_GEOMETRY类型。SDO_GEOMETRY表示一个几何对象,可以是点、线、面、多点、多线、多面或混合对象。 Spatial 在此数据类型的基础上,实现了R树空间索引和四*树空间索引,还以sql函数的形式实现了多种空间分析功能。 Oracle Spatial 使用: 1、将SDO_GEOMETRY数据类型作为数据表的一个列。 CREATE TABLE cola_markets ( mkt_id NUMBER PRIMARY KEY, name VARCHAR2(32), shape MDSYS.SDO_GEOMETRY); 2、填写空间元数据。 INSERT INTO USER_SDO_GEOM_METADATA VALUES ( 'cola_markets', 'shape', MDSYS.SDO_DIM_ARRAY( -- 20X20 grid MDSYS.SDO_DIM_ELEMENT('X', 0, 20, 0.005), MDSYS.SDO_DIM_ELEMENT('Y', 0, 20, 0.005) ), NULL -- SRID ); 3、创建空间索引。 CREATE INDEX cola_spatial_idx

远程win10系统桌面时提示凭证不工作问题的终极解决办法

环境说明 被远程电脑(WIN10系统) 远程连接客户机(WIN7,WIN8,WIN10) 故障现象 最近在使用远程桌面连接自己宿舍电脑,突然发现win10系统总是无法连接成功,提示“你的凭证不工作”,使用其他人的win7、win8的连接也是出现这个问题。 有问题上百度,可百度好久发现千篇一律的做法基本如下所示 一,策略修改法, 1、在“开始”窗口运行gpedit.msc,进入计算机配置->管理模板->系统->凭据分配->允许分配保存的凭据用于仅NTLM服务器身份验证,双击打开,选择“已启用”->单击“显示”输入“TERMSRV/*”,点确定后退出。 2,在“开始”窗口运行命令“gpupdate /force”立即生效或重启电脑。 经测试,此方法对我的情况无效。 二,添加凭据: 1、进入“控制面板”->“凭据管理器”->“添加Windows凭据”->输入 要登录的服务器的IP地址、用户名、密码,点确定退出。 经测试,此方法对我的情况无效。 无论怎么尝试都无效,因此断定问题不在客户机电脑,而是公司那台办公电脑的某些设置不对,想想最近对办公电脑做过哪些操作,还真是做过一些操作(前几天因公司电脑突然变得奇慢无比,自己做过优化,优化后速度很快了)现在无法确定是否跟电脑优化有关,无奈之下只能死马当活马医了,搞不好大不了重装系统。 打开本地组策略编辑器,看下有关系统安全设置的选项,看看是否有什么限制,多次尝试中,发现了解决方法,整理步骤如下: 开始-->运行->gpedit.msc->计算机配置->Windows设置->安全设置->本地策略->安全选项->网络访问:本地帐户的共享和安全模型。 修改为使用经典模式,如下图示 保存后,再次连接,即刻生效!!

Qt之QHostInfo

简述 QHostInfo 类为主机名查找提供了静态函数。 QHostInfo 利用操作系统提供的查询机制来查询与特定主机名相关联的主机的 IP 地址,或者与一个IP地址相关联的主机名。这个类提供了两个静态的便利函数:一个以异步方式工作,一旦找到主机就发射一个信号;另一个以阻塞方式工作,并且最终返回一个 QHostInfo 对象。 要使用异步方式查询主机的 IP 地址,调用 lookupHost() 即可,该函数包含 3 个参数,依次是:主机名/ IP 地址、接收的对象、接收的槽函数,并返回一个查询ID。以查询ID为参数,通过调用 abortHostLookup() 函数的来中止查询。 当获得查询结果后就会调用槽函数,查询结果被存储到 QHostInfo 对象中。可通过调用 addresses() 函数来获得主机的 IP 地址列表,同时可通过调用 hostName() 函数来获得查询的主机名。 简述查询本机主机名 查询主机信息 异步方式阻塞方式中止查询错误处理更多参考 查询本机主机名 QString strLocalHostName = QHostInfo::localHostName(); qDebug() << "Local Host Name:" << strLocalHostName; 输出结果: Local Host Name:”Wang-PC” 查询主机信息 异步方式 使用 lookupHost() ,实际的查询在一个单独的线程中完成,利用操作系统的方法来执行名称查找。 根据主机名查询主机信息 int nID = QHostInfo::lookupHost("qt-project.org", this, SLOT(lookedUp(QHostInfo))); void MainWindow::lookedUp(const QHostInfo &host) { if (host.error() != QHostInfo::NoError) { qDebug() << "

在maven的pom文件中引入servlet-api的方法

问题:maven项目提示superclass.servlet报错。 在项目的.pom文件中的添加dependency属性如下: <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> 即可。 或者直接使用eclipse的:右键项目名称-》maven->Add Dependencies->在搜索栏输入servlet,选中相关依赖即可,比如:javax.servlet-api 。eclipse会自动匹配最新版本号。

Java访问远程接口的几种方式

一、Java访问远程url接口并获取结果 1、原生JavaAPI获取 package com.util; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.Map; /** * <pre> * 功能:httpUrlConnection访问远程接口工具 * 日期:2015年3月17日 上午11:19:21 * </pre> */ public class HttpUrlConnectionUtil { /** * <pre> * 方法体说明:向远程接口发起请求,返回字符串类型结果 * @param url 接口地址 * @param requestMethod 请求方式 * @param params 传递参数 重点:参数值需要用Base64进行转码 * @return String 返回结果 * </pre> */ public static String httpRequestToString(String url, String requestMethod, Map<String, String> params){ String result = null; try { InputStream is = httpRequestToStream(url, requestMethod, params); byte[] b = new byte[is.

勿在头文件中定义static变量

一、问题 看到有一位同学在头文件中这么写: static const wchar_t* g_str1 = … static const wchar_t* g_str2 = … 这种定义变量的方式我从来没有见过,而且它还能顺利通过编译,于是我很想知道编译器是如何处理这种变量定义的。 定义全局变量时使用static,意味着该变量的作用域只限于定义它的源文件中,其它源文件不能访问。既然这种定义方式出现在头文件中,那么可以很自然地推测:包含了该头文件的所有源文件中都定义了这些变量,即该头文件被包含了多少次,这些变量就定义了多少次。 假如将上面两行代码的static去掉,编译的时候就会出现变量重定义的错误,这进一步证实了上面的推测,因为没有static的话变量的作用域是全局的,定义了两个以上的同名变量就会出现该错误。 推测终究是推测,要真正证实这个推测还要通过写代码来验证。验证的方式是:在头文件中使用static定义变量,在多个源文件中包含该头文件,然后在每个源文件中输出变量的地址,同时在一个源文件中改变变量的值并输出,在另一个源文件中也输出。如果每个源文件的输出都不同,则推测得证;否则推测是错误的。 二、验证 下面是定义变量的头文件的代码: //Header.h #pragma once static int g_int = 3; 接下来在另一个头文件中声明两个测试函数: //Functions.h #pragma once void TestSource1(); void TestSource2(); 分别在两个源文件中定义这两个测试函数: //Source1.cpp #include <stdio.h> #include "Header.h" void TestSource1() { wprintf(L"g_int's address in Source1.cpp: %08x\n", &g_int); g_int = 5; wprintf(L"g_int's value in Source1.cpp: %d\n", g_int); } //Source2.cpp #include <stdio.h> #include "Header.h" void TestSource2() { wprintf(L"

解决vi编辑器不能使用方向键和退格键问题

使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多字母 这个问题主要是新系统直装了vi,没有装vim。因为vi是不能直接按退格键删除字符的,所以当你使用退格键删除字符,只有在按下esc时,那些字符才会消失。。。vim可以直接像记事本一样编辑字符! 在网上找了个方法 问题已经解决 分享一下: 只要依次执行以下两个命令即可完美解决Ubuntu下vi编辑器方向键变字母的问题。 一.执行命令 sudo apt-get remove vim-common 二.执行命令 sudo apt-get install vim 再试试Vi编辑器,是不是恢复正常了。

java IO 流Stream 序列化Serializable 文件File

一、什么是流 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输出操作都是以“流”的方式进行。设备可以是文件,网络,内存等。 流具有方向性,至于是输入流还是输出流则是一个相对的概念,一般以程序为参考,如果数据的流向是程序至设备,我们成为输出流,反之我们称为输入流。 可以将流想象成一个“水流管道”,水流就在这管道中形成了,自然就出现了方向的概念。 当程序需要从某个数据源读入数据的时候,就会开启一个输入流,数据源可以是文件、内存或网络等等。相反地,需要写出数据到某个数据源目的地的时候,也会开启一个输出流,这个数据源目的地也可以是文件、内存或网络等等。 二、流的分类 可以从不同的角度对流进行分类: 处理的数据单位不同,可分为:字符流,字节流 数据流方向不同,可分为:输入流,输出流 功能不同,可分为:节点流,处理流 1 和 2 都比较好理解,对于根据功能分类的,可以这么理解: 节点流:节点流从一个特定的数据源读写数据。即节点流是直接操作文件,网络等的流,例如FileInputStream和FileOutputStream,他们直接从文件中读取或往文件中写入字节流。 处理流:“连接”在已存在的流(节点流或处理流)之上通过对数据的处理为程序提供更为强大的读写功能。过滤流是使用一个已经存在的输入流或输出流连接创建的,过滤流就是对节点流进行一系列的包装。例如BufferedInputStream和BufferedOutputStream,使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,以及DataInputStream和DataOutputStream,使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。他们都属于过滤流。 举例: import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.BufferedInputStream; public class StreamTest { public static void main(String[] args) throws IOException { // 节点流FileOutputStream直接以A.txt作为数据源操作 FileOutputStream fileOutputStream = new FileOutputStream("A.txt"); // 过滤流BufferedOutputStream进一步装饰节点流,提供缓冲写 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( fileOutputStream); // 过滤流DataOutputStream进一步装饰过滤流,使其提供基本数据类型的写 DataOutputStream out = new DataOutputStream(bufferedOutputStream); out.writeInt(3); out.writeBoolean(true); out.flush(); out.close(); // 此处输入节点流,过滤流正好跟上边输出对应,读者可举一反三 DataInputStream in = new DataInputStream(new BufferedInputStream( new FileInputStream("

线上Nginx跳转存在的接口返回异常问题

问题描述 最近一次上线本来是个很简单的功能,却被折腾了一宿,痛苦不堪啊!问题是这样的,线上发布完成以后,发现登录接口无法正常返回数据,但该接口涉及到的代码却根本就没有更改。 问题排查 出现这个问题,首先想到的肯定是接口是否出现了问题。于是开始对这个接口进行测试验证,经过在本机和测试环境验证,该接口不存在任何问题,但调用线上的接口却出现问题,无数据返回。使用chrome浏览器调试,发现接口返回“net::ERR_EMPTY_RESPONSE”这样的错误信息。于是从这个错误信息开始排查。上网上搜索相关信息,没有非常好的解决方法。 后来,对后台接口日志进行监控,发现偶尔会出现connection reset的异常信息,并且还发现前端调一次接口,后端日志却显示该接口被调用了两次。发现这些规律后,笔者开始对线上环境的服务器调用方式进行了解。经过与运维了解,线上环境是通过Nginx进行转发请求。笔者开始注意chrome浏览器中的请求情况,发现客户端请求Nginx不存在问题,但Nginx转发请求到接口服务器就出现了问题。发现这个现象后,笔者请运维确认Nginx是否存在异常情况,被告知没有异常。但是运维对Nginx服务器进行重启,笔者再次进行测试,问题无法复现。

ueditor实例销毁重建

需求是做一个留言回复 留言回复框会在不同的位置出现 需要不停地销毁重建 一开始直接用js删除div标签 但是再次使用UE.getEditor方法就失效了 看了ueditor的api 有用destroy()的方法 发现使用后 会让div标签变成 textare标签 所以使用后想完全消除 还要去掉textare标签才行

ueditor实例销毁重建 ...

需求是做一个留言回复 留言回复框会在不同的位置出现 需要不停地销毁重建 一开始直接用js删除div标签 但是再次使用UE.getEditor方法就失效了 看了ueditor的api 有用destroy()的方法 发现使用后 会让div标签变成 textare标签 所以使用后想完全消除 还要去掉textare标签才行 转载于:https://www.cnblogs.com/lovejj1994/p/7182187.html

JQuery和JS操作LocalStorage/SessionStorage的方法

首先说一下LocalStorage和SessionStorage LocalStorage 是对Cookie的优化没有时间限制的数据存储在隐私模式下不可读取大小限制在500万字符左右,各个浏览器不一致在所有同源窗口中都是共享的本质是在读写文件,数据多的话会比较卡(firefox会一次性将数据导入内存)不能被爬虫爬取,不要用它完全取代URL传参IE7及以下不支持外,其他标准浏览器都完全支持 SessionStorage 针对一个 session 的数据存储大小限制在5M左右,各个浏览器不一致仅在当前浏览器窗口关闭前有效(适合会话验证)不在不同的浏览器窗口中共享,即使是同一个页面 JS下的操作方法 获取键值:localStorage.getItem(“key”)设置键值:localStorage.setItem(“key”,”value”)清除键值:localStorage.removeItem(“key”)清除所有键值:localStorage.clear()获取键值2:localStorage.keyName设置键值2:localStorage.keyName = “value” JQ下的操作方法(JS方法前加”window.”) 获取键值:window.localStorage.getItem(“key”)设置键值:window.localStorage.setItem(“key”,”value”)清除键值:window.localStorage.removeItem(“key”)清除所有键值:window.localStorage.clear()获取键值2:window.localStorage.keyName设置键值2:window.localStorage.keyName = “value” 示例 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript" charset="utf-8" src="js/jquery.min.js"></script> <script type="text/javascript"> // JS操作部分 localStorage.JSa="JSA"; document.write(localStorage.JSa); localStorage.setItem('JSb','&nbsp;JSB'); document.write(localStorage.getItem('JSb')); // JQuery操作部分 $(function(){ window.localStorage.JQa="JQA"; $("#a").text(window.localStorage.JQa); window.localStorage.setItem('JQb','JQB'); $("#b").text(window.localStorage.getItem('JQb')); }); </script> </head> <body> <p id="a"></p> <p id="b"></p> </body> </html> 运行结果: 注:typeOf(localStorage.keyName)可与”undefined”进行判断该键值是否已存在

linux内核里的GPIO操作函数

1.gpio_set_value(unsigned gpio, int value)用来设置gpio寄存器的值 2.gpio_direction_output(unsigned gpio, int value)用来设置gpio为输出功能,同时设置gpio输出的值。 一般来说,设置一个GPIO口为输出,先执行一次gpio_direction_output,然后接下来只需执行gpio_set_value就行了。 3.gpio_direction_input(unsigned gpio)用来设置gpio为输入功能 4.gpio_get_value(unsigned gpio)用来获取gpio口的输入的值; 5.在使用gpio口之前,先用gpio_request(unsigned gpio, const char* label)申请gpio口的使用,若申请成功,则说明该gpio口未被使用。 6.在使用完gpio口之后,用gpio_free(unsigned gpio)释放gpio口。 7.如何获取gpio口呢,可以查看内核中对应版型的相关文件,也可以自己进行计算,比如GPIOA1的gpio为1,GPIOB2为34。 8.gpio口的通用函数接口定义在gpiolib.c文件中,声明则在gpio.h中。

ubuntu 创建用户

在Ubuntu中创建新用户,通常会用到两个命令:useradd和adduser。 1. 使用useradd时,如果后面不添加任何参数选项,例如:#sudo useradd test创建出来的用户将是默认“三无”用户:一无Home Directory,二无密码,三无系统Shell。 2.使用adduser时,创建用户的过程更像是一种人机对话,系统会提示你输入各种信息,然后会根据这些信息帮你创建新用户。 以下新建用户步骤: 一、新建用户 www.linuxidc.com adduser 新建用户的名字 二、创建并设置home目录 #cd /home 1.创建home目录: # mkdir 新建用户的名字 2.拷贝环境变量模板文件: # cp /etc/skel/.b* 新建用户的名字 # cp /etc/skel/.p* 新建用户的名字 3.修改权限 # chown -R 新建用户的名字 /home/新建用户的名字 # chmod 770 /home/新建用户的名字 三、赋予ROOT权限 root@ubuntu:~# sudo vim /etc/sudoers 修改文件如下: # User privilege specification root ALL=(ALL) ALL db ALL=(ALL) ALL 保存退出,db用户就拥有了root权限。

SQL 判断年份是否为润年

DROP FUNCTION [dbo].[fn_IsLeapYear] GO /****** Object: UserDefinedFunction [dbo].[fn_IsLeapYear] Script Date: 2016/2/25 13:22:50 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO /* select dbo.[fn_IsLeapYear] (year(getdate())) select dbo.[fn_IsLeapYear] (2008) select dbo.[fn_IsLeapYear] (2001) */ create function [dbo].[fn_IsLeapYear] ( @year int ) returns varchar(14) as begin declare @returnvalue int ----varchar(14) declare @setvalue int set @setvalue=datepart(mm,dateadd(dd,1,cast((cast(@year as varchar(4))+ '0228') as datetime))) if(@setvalue=2) set @returnvalue=1 ---@returnvalue='闰年' else set @returnvalue=0 ---@returnvalue='非闰年' ----return (cast (@year as varchar(8))+'年:'+@returnvalue) return @returnvalue end GO V2:

Linux服务启动报:Address already in use 解决方法:预留端口避免占用ip_local_reserved_ports

问题描述: 业务遇到这个情况,在重启服务时,出现50020端口被占用而无法启动, 非得等该端口释放后才启动成功。 问题分析: 50020端口被该服务器上的客户端 随机选取源端口给占用掉了。 解决方案: 使用net.ipv4.ip_local_port_range参数,规划出一段端口段预留作为服务的端口, 这种方法是可以解决当前问题,但是会有个问题,端口使用量减少了, 当服务器需要消耗大量的端口号的话,比如反代服务器,就存在瓶颈了。 最好的做法是将服务监听的端口以逗号分隔全部添加到ip_local_reserved_ports中, TCP/IP协议栈从ip_local_port_range中随机选取源端口时, 会排除ip_local_reserved_ports中定义的端口, 因此就不会出现端口被占用了服务无法启动。 ip_local_reserved_ports解释如下: ip_local_reserved_ports - list of comma separated ranges Specify the ports which are reserved for known third-party applications. These ports will not be used by automatic port assignments (e.g. when calling connect() or bind() with port number 0). Explicit port allocation behavior is unchanged. The format used for both input and output is a comma separated list of ranges (e.

java 对象克隆

为什么需要克隆: 在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需求的,要满足这种需求有很多途径 克隆的实现方式 2.1. 浅度克隆,使用clone 对于要克隆的对象,对于其基本数据类型的属性,复制一份给新产生的对象,对于非基本数据类型的属性,仅仅复制一份引用给新产生的对象,即新产生的对象和原始对象中的非基本数据类型的属性都指向的是同一个对象。 1、实现java.lang.Cloneable接口 要clone的类为什么还要实现Cloneable接口呢?Cloneable接口是一个标识接口,不包含任何方法的!这个标识仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object的 clone()方法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出 CloneNotSupportedException异常。 2、重载java.lang.Object.clone()方法 JDK API的说明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。 观察一下Object类的clone()方法是一个native方法,native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Object中clone()方法而不是先new一个类,然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。Object类中的clone()还是一个protected属性的方法,重载之后要把clone()方法的属性设置为public。 Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。 class Teacher { public int age; public String name; public int getAge(){ return age; } public void setAge(int age){ this.age = age; } public String getName(){ return name; } public void setName(String name){ this.name = name; } @Override public String toString() { return "Teacher [age= " + age + " , name= " + name + "

centos-系统语言检查设置安装

查看当前系统语言 登陆linux系统打开操作终端之后,输入 echo $LANG可以查看当前使用的系统语言。 查看安装的语言包 查看是否有中文语言包可以在终端输入 locale命令,如有zh cn 表示已经安装了中文语言 果没有中文语言呢 可以通过网上下载安装中文语言包yum groupinstall chinese-support) 如何修改系统语言为中文 1 临时更换语言 如果只是临时更换linux系统的语言环境,可以通过输入设置 LANG=语言名称, 如中文是 Zn_CN.UTF-8(注意我这里本来就是中文的,我临时设置为英文 2.修改系统默认语言 以上方法是通过修改设置系统默认的语言配置 如Vi /etc/sysconfig/i18n (注意改好之后重启一下系统) 转载于:https://www.cnblogs.com/baxk/p/5212031.html

C++标准库中正则表达式简介

C++标准库中正则表达式的使用 qianghaohao #include <iostream> #include <sstream> #include <fstream> #include <string> #include <regex> using namespace std; /// /// C++标准库中正则表达式的使用简介: /// C++标准库中提供了对正表达式的支持,以下是常用的使用方法. /// /// regex类:定义包含正则表达式的对象,如:regex rx("a(b?)c"); /// /// cmatch类:Type definition for char match_results.用来 /// 定义保存匹配结果的对象-->typedef match_results<const char*> cmatch; /// 当待搜索的字符串是char类型是,使用此类对象 /// /// smatch类:Type definition for string match_results.用来 /// 定义保存匹配结果的对象-->typedef match_results<string::const_iterator> smatch; /// 当待搜索的字符串是string类型是,使用此类对象 /// /// ==========================以下是三个常用的正则匹配函数================================== /// *bool regex_match(...)函数:Exactly matches a regular expression,判断是否准确匹配 * /// *Tests whether a regular expression matches the entire target string * /// *是否准确匹配整个目标字符串 * /// *注意:regex_match是目标字符串和正则表达式要完全匹配时才返回true.

给eclipse装一些插件

最近换了一个环境,需要折腾一个新的eclipse配置,所以在这里记录下。 1.安装marketplace help=>install,输入地址:http://download.eclipse.org/mpc/<代号>/,各版本代号如下: Eclipse 3.1 版本代号 IO 【木卫1,伊奥】 Eclipse 3.2 版本代号 Callisto 【木卫四,卡里斯托 】 Eclipse 3.3 版本代号 Eruopa 【木卫二,欧罗巴 】 Eclipse 3.4 版本代号 Ganymede 【木卫三,盖尼米德 】 Eclipse 3.5 版本代号 Galileo 【伽利略】 Eclipse 3.6 版本代号 Helios 【太阳神】 Eclipse 3.7 版本代号 Indigo 【靛青】 Eclipse 4.2 版本代号 Juno 【婚神星】 Eclipse 4.3 版本代号 Kepler 【开普勒】 比如我的是:http://download.eclipse.org/mpc/juno/ 安装好插件市场后,就可以去help=>Eclipse Marketplace里可视化安装插件了,相当方便。 2.右键打开文件所在目录插件 转载于:https://www.cnblogs.com/fwindpeak/p/5207853.html

audio的输出设备切换分析

本文主要介绍android上音频输出设备切换的代码流程 (此文部分内容参考自邓凡达老师的博客。感谢邓老师讲解) 上层程序要切换输出设备时,经过JNI调用,会调用AudioSystem::setForceUse status_t AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; return aps->setForceUse(usage, config); } 接下来就是调用frameworks/av/services/audioflinger/AudioPolicyService.cpp的setForceUse()函数了; status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) { Mutex::Autolock _l(mLock); mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config); return NO_ERROR; } AP章节中,我们介绍过,mpAudioPolicy实际上是在AudioServicePolicy.cpp的构造函数中被赋值,可以理解成是指向了AP HAL层的handle mpAudioPolicy->set_force_use实际上调用的是audio_policy_hal.cpp里面的ap_set_force_use。 static void ap_set_force_use(struct audio_policy *pol, audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) { struct legacy_audio_policy *lap = to_lap(pol); lap->apm->setForceUse((AudioSystem::force_use)usage, (AudioSystem::forced_config)config); } 继而调用AudioPolicyManagerBase::setForceUse void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) { .... checkA2dpSuspend(); checkOutputForAllStrategies(); updateDevicesAndOutputs(); //各种内部状态的更新 for (size_t i = 0; i < mOutputs.

android audio 音量设置分析

audiod 中经常遇到的场景是音量调整与输出设备的切换,下面两篇文章 针对这两个场景分别分析一下 1,音量调整场景 android 音量调整,可以使用两种方式: 软件mixer的时候修改PCM data 控制DAC硬件的增益 第一种情况,如果是多路mix的情况,就是MixerThread进行软件mixer,然后在mixer计算的时候来缩放PCM data, 首先,JNI层调用了AudioFlinger::setStreamVolume。 status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, audio_io_handle_t output) { AutoMutex lock(mLock); PlaybackThread *thread = NULL; if (output) { thread = checkPlaybackThread_l(output); //获得对应的PlaybackThread if (thread == NULL) { return BAD_VALUE; } } if (thread == NULL) { for (size_t i = 0; i < mPlaybackThreads.size(); i++) { mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value); } } else { thread->setStreamVolume(stream, value); //继续向下层设置 } return NO_ERROR; }可以看到,最终是调用了PlaybackThread::setStreamVolume来继续设置音量 void AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) { Mutex::Autolock _l(mLock); mStreamTypes[stream].

事务 C#中TransactionScope的使用方法和原理

摘自:http://cnn237111.blog.51cto.com/2359144/1271600 在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务的处理,都交给了SqlTransaction和SqlConnection,每个Transaction是基于每个Connection的。这种设计对于跨越多个程序集或者多个方法的事务行为来说,不是非常好,需要把事务和数据库连接作为参数传入。 在.net2.0后,TransactionScope类的出现,大大的简化了事务的设计。示例代码如下: static void Main(string[]args) { using (TransactionScopets = new TransactionScope()) { userBLLu = new userBLL(); TeacherBLLt = new TeacherBLL(); u.ADD(); t.ADD(); ts.Complete(); } } 只需要把需要事务包裹的逻辑块写在using (TransactionScope ts = newTransactionScope())中就可以了。从这种写法可以看出,TransactionScope实现了IDispose接口。除非显示调用ts.Complete()方法。否则,系统不会自动提交这个事务。如果在代码运行退出这个block后,还未调用Complete(),那么事务自动回滚了。在这个事务块中,u.ADD()方法和t.ADD()方法内部都没有用到任何事务类。 TransactionScope是基于当前线程的,在当前线程中,调用Transaction.Current方法可以看到当前事务的信息。具体关于TransactionScope的使用方法,已经它的成员方法和属性,可以查看MSDN。 TransactionScope类是可以嵌套使用,如果要嵌套使用,需要在嵌套事务块中指定TransactionScopeOption参数。默认的这个参数为Required。 static void Main(string[]args) { using (TransactionScopets = new TransactionScope()) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); userBLLu = new userBLL(); TeacherBLLt = new TeacherBLL(); u.ADD(); using (TransactionScopets2 = new TransactionScope(TransactionScopeOption.Required)) { Console.WriteLine(Transaction.Current.TransactionInformation.LocalIdentifier); t.ADD(); ts2.Complete(); } ts.Complete(); } } 当嵌套类的TransactionScope的TransactionScopeOption为Required的时候,则可以看到如下结果,他们的事务的ID都是同一个。并且,只有当2个TransactionScope都complete的时候才能算真正成功 如果把TransactionScopeOption设为RequiresNew,则嵌套的事务块和外层的事务块各自独立,互不影响

Mybatis自动生成实体类,映射文件,以及dao层接口。

Mybatis不像Hibernate那样可以直接通过Myeclipse直接生成相应的映射文件,它是一个半自动化的ORM框架,所以主要的工作就是配置Mapping映射文件,但是由于手写映射文件很容易出错,所以可利用MyBatis生成器自动生成实体类、DAO接口和Mapping映射文件。这样可以省去很多的功夫,将生成的代码copy到项目工程中即可。 所需要的文件如下: 主要是配置generatorConfig.xml这个文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- mysql-connector文件路径 --> <classPathEntry location="mysql-connector-java-5.1.25-bin.jar"/> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 链接配置 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/ssm" userId="root" password="root"> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- 生成实体类的路径,com.project.ssm.entity 这个路径可以自动生成,但是必须有src这个路径--> <javaModelGenerator targetPackage="com.project.ssm.entity" targetProject="src"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- 生成实体类的路径,这个路径可以自动生成,但是必须有src这个路径--> <sqlMapGenerator targetPackage="com.project.ssm.mapping" targetProject="src"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <javaClientGenerator type="

uva 1380 - A Scheduling Problem 一个调度问题 好难的动态规划

想不出来啊!!!,紫书上写的很清楚。 1.利用题目给出的图论定理,先不考虑无向边,假如图中有向链的最大长度为K,那么答案为K+1或K+2(注意是K链的长度,答案是链包含点的个数)。 2.考虑答案是否能为K+1,否则为K+2,即考虑给无向边定向,定向之后能否使最长链不超过K? 进行动态规划来考虑: 对于每一个结点 in[x] 表示: 在定向后最长链不超过K的前提下,终点为该结点的有向链中最大长度的最小值。 out[x]表示:在定向后最长链不超过K的前提下,起点为该结点的有向链中最大长度的最小值。 设置一个变量ok,赋初值=1,对于每一个点都要验证这个题目是否能满足条件,如果某一个点不能满足,ok=0。 如果ok最后==0,那么答案K+2,否则K+1。 动态规划可解的原因: 满足最优子结构、无后效性: 对于某一个结点,先验证他与子结点相连的边中的定向边,看看最长的出发链和最长的进入链长度之和能否<=K, 如果不行,ok=0;return; 否则,接下来对无向边进行定向,枚举无向边相连的子结点,以求in[x]为例, in[x]={ 定向边中进入链最大值, 不定向的边中将某些边定为进入方向 ,可取到的进入链的最小值 } (只考虑与子结点相连的边) 按照未定向边连接的子结点的in[x]从小到大排序,按照此顺序逐一验证能否存在一条边,使最长进入链+最长出发链<=K,每验证一条边,该边包含前面的边都定向为进入边,若存在in[x]={ 定向边中进入链最大值, 该条链的长度 } (只考虑与子结点相连的边) 注意可能全部定向为出发边。 out[x]求法... 对于某一个结点,如果有定向边,通过定义 又不存在合法的进入链,那么in[x]=INF, 对于一个结点如果in[x]==out[x]==INF,那么ok=0,否则ok=1; (对于一个结点,可能不存在合法的进入链,但可能存在合法的出发链,这样也能使之合法) 最优子结构: 每个结点算出来的in[x]、out[x]都是合法情况下通过规划方法给边定向所得进入链,出发链的最大长度最小值,所以如果把这些值带到父结点验算,仍然不能满足条件,那么肯定就不存在使父结点为子树满足条件的规划(定向)方法。 题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4126 点我 /**========================================== * This is a solution for ACM/ICPC problem * * @source: uva 1380 - A Scheduling Problem * @type: dp * @author: wust_ysk * @blog: http://blog.csdn.net/yskyskyer123 * @email: 2530094312@qq.com *===========================================*/ #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int INF =0x3f3f3f3f; const int maxn=200 ; //const int maxV=12 ; int n,K,now; bool ok; int in[maxn+4],out[maxn+4],root; int dp[maxn+4][3]; int pre[maxn+4]; bool vis[maxn+4]; struct Edge { int to; char type ; Edge(){} Edge(int to,char type):to(to),type(type){} }; vector<Edge >G[maxn+4]; void init() { for(int i=1;i<=maxn;i++) G[i].

接口逆向

使用 Fiddler 进行抓包,分析请求地址与参数 反编译 使用 dex2jar 以及 jd-gui 进行反编译,分析 签名生成过程。

linux命令学习之(ifconfig)

ifconfig命令 许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改。Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config)。通常需要以root身份登录或使用sudo以便在Linux机器上使用ifconfig工具。依赖于ifconfig命令中使用一些选项属性,ifconfig工具不仅可以被用来简单地获取网络接口配置信息,还可以修改这些配置。 1.命令格式: ifconfig [网络设备] [参数] 2.命令功能: ifconfig 命令用来查看和配置网络设备。当网络环境发生改变时可通过此命令对网络进行相应的配置。 3.命令参数: up 启动指定网络设备/网卡。 down 关闭指定网络设备/网卡。该参数可以有效地阻止通过指定接口的IP信息流,如果想永久地关闭一个接口,我们还需要从核心路由表中将该接口的路由信息全部删除。 arp 设置指定网卡是否支持ARP协议。 -promisc 设置是否支持网卡的promiscuous模式,如果选择此参数,网卡将接收网络中发给它所有的数据包 -allmulti 设置是否支持多播模式,如果选择此参数,网卡将接收网络中所有的多播数据包 -a 显示全部接口信息 -s 显示摘要信息(类似于 netstat -i) add 给指定网卡配置IPv6地址 del 删除指定网卡的IPv6地址 <硬件地址> 配置网卡最大的传输单元 mtu<字节数> 设置网卡的最大传输单元 (bytes) netmask<子网掩码> 设置网卡的子网掩码。掩码可以是有前缀0x的32位十六进制数,也可以是用点分开的4个十进制数。如果不打算将网络分成子网,可以不管这一选项;如果要使用子网,那么请记住,网络中每一个系统必须有相同子网掩码。 tunel 建立隧道 dstaddr 设定一个远端地址,建立点对点通信 -broadcast<地址> 为指定网卡设置广播协议 -pointtopoint<地址> 为网卡设置点对点通讯协议 multicast 为网卡设置组播标志 address 为网卡设置IPv4地址 txqueuelen<长度> 为网卡设置传输列队的长度 4.使用实例: 实例1:显示网络设备信息(激活状态的) 命令: ifconfig 说明: eth0 表示第一块网卡, 其中 HWaddr 表示网卡的物理地址,可以看到目前这个网卡的物理地址(MAC地址)是 00:50:56:BF:26:20 inet addr 用来表示网卡的IP地址,此网卡的 IP地址是 192.168.120.204,广播地址, Bcast:192.168.120.255,掩码地址Mask:255.255.255.0 lo 是表示主机的回坏地址,这个一般是用来测试一个网络程序,但又不想让局域网或外网的用户能够查看,只能在此台主机上运行和查看所用的网络接口。比如把 HTTPD服务器的指定到回坏地址,在浏览器输入 127.

数据结构(1)--线性表顺序表的主要操作的实现

参考书籍:数据结构(C语言版) 严蔚敏 吴伟民编著 清华大学出版社 本文中的代码可从这里下载:https://github.com/qingyujean/data-structure 1.基本定义 #include<stdio.h> //顺序表:1.使用动态分配的一维数组 // 2.使用静态分配的一维数组 //本实例使用静态分配 #define LIST_INIT_SIZE 100 typedef int ElemType; typedef struct SqList{ ElemType data[LIST_INIT_SIZE]; int len; }SqList; 2.创建线性表和打印输出线性表 //创建一个长度为n的顺序线性表 void createSqList(SqList &L, int n){ printf("请输入%d个数:\n", n); for(int i = 0; i < n; i++){ scanf("%d",&L.data[i]); } L.len = n; //printSqList(L); } //打印输出顺序线性表 void printSqList(SqList L){ printf("打印线性表:"); for(int i = 0; i < L.len; i++){ printf("%d ",L.data[i]); } printf("\n"); } 演示: int main(){ //初始化一个空的线性表 SqList L; L.

纯干货:Linux抓包命令集锦

/****************************************************************************************** * 版权声明 * 本文为本人原创,本人拥有此文的版权。鉴于本人持续受益于开源软件社区, * 本人声明:任何个人及团体均可不受限制的转载和复制本文,无论是否用于盈利 * 之目的,但不得修改文章内容,并必须在转载及复制时同时保留本版权声明,否 * 则为侵权行为,本人保留追究相应主体法律责任之权利。 * speng2005@gmail.com * 2016-1 ******************************************************************************************/ 大道至简! 相信抓包是程序员,运维工程师,架构师,都必不可少的一项技能。但是能够深入掌握好这门技艺的人,确实需要有开发,网络,运维,架构等"跨界”背景才能比较好的发挥抓包神技的威力。本文是纯干货,重点不在于理论,更注重实战技能,尤其注重对抓包数据的分析。本文中的命令追求的是使用最简单,最普及的Linux系统自带工具包实现各种抓包分析,具有尽可能广泛的移植性和可用性。文中给出的命令均在Centos 6.3,tcpdump 4.1版本下测试可用;其他平台及环境,可能需要你自己微调部分命令及脚本才可以运行。文中多数命令及脚本都严重依赖于tcpdump命令输出文本数据格式,微调代码时应格外注意这一点。注意,本文中的命令适用于一般的基于tcp连接的,请求响应模型的网络服务,但不适用于使用pipeline模式的网络服务。如果想理解本文命令思路的话,需要你熟悉tcp/ip协议,网络osi模型,常见网络通讯协议,socket编程,linux脚本编程,awk脚本编程,数据挖掘思维方式等知识,不足者请自行脑补。理解本文的思路后,还可以在这些命令基础上有许多种灵活搭配和变种,请自行研究。不想费脑细胞的,运气好的话,很多命令都可以直接使用。尽管这里讲的是Linux抓包,但如果使用流行的wireshark在Windows上抓包后保存成tcpdump格式文件,然后上传到Linux系统上照样可以使用本文中的命令进行分析。 1.盲抓 盲抓就是瞎抓,尤其在你接触到一台陌生机器,感觉有点抓瞎的时候,应当使用本节中的方法,其目的是找出这台机器上的重点网络服务是哪些ip和端口。如果你明确的知道要抓的包是哪个ip,哪个端口,可以直接跳至下一小节。 在目标机器上抓取任意tcp数据(需要root权限): tcpdump -i any -nn tcp > 123.pkg.head.txt分析目标机器上热点ip:port(按数据包数量统计): cat 123.pkg.head.txt | awk 'NF>5 && $2=="IP" {print $3,"[out]"; print substr($5,1,length($5)-1), "[in]"}' | sort | uniq -c | awk '{buf[NR]=$0;sum+=$1} END{for(i=1;i<=NR;i++) print buf[i], sum}' | awk '{printf("%s %s %s %.2f %%\n",$1, $2, $3, 100*$1/$4)}' | sort -nr -k 4 | less 示例: 2359 10.

使用pabot并发执行robotframework的testSuite

下载robotremoteserver-1.0.1.tar.gz、robotframework-pabot-0.22.tar.gz 执行以下命令,以安装pabot: pip install robotremoteserver-1.0.1.tar.gz pip install robotframework-pabot-0.22.tar.gz 以下命令,可并行执行parallelSuits文件夹内的所有testSuite,并把结果输出到results目录内: pabot --processes 10 --outputdir results parallelSuits/ pabot还提供了一些用于并发同步的关键字,如需使用,在并发执行的testSuite中可import相关Library:pabot.PabotLib

Three.js typescript definitely typed 文件

最近学习three.js,想用typescript编写代码,去http://definitelytyped.org/找了一圈没有发现three.js的definitely typed文件. 好吧,花了2天时间自己简单写了一份: declare module THREE { export class BoxHelper extends Line { constructor(object: Object3D); public update(object: Object3D); } export class DrawTextResult { public paths: any[]; public offset: number; } export class FontUtils { public static divisions: number; public static style: string; public static weight: string; public static face: string; public static faces: any; public static size: number; public static drawText(text: string): DrawTextResult; public static Triangulate(contour: Vector2[], indices: boolean): any[]; public static extractGlyphPoints(c: string, face: string, scale: number, offset: number, path: Path); } export class Curve { constructor(); public getPoint(t: number): any; public getPointAt(u: number): any; public getPoints(divisions: number[]): any[]; public getSpacedPoints(divisions: number): any[]; public getLength(): number; public getLengths(divisions: number): number[]; public updateArcLengths(): void; public getTangent(t: number): any; public getTangentAt(u: number): any; } export class CurvePath extends Curve { constructor(); public curves: Curve[]; public bends: Curve[]; public autoClose: boolean; public getWrapPoints(vertices: Vector2[], curve: Curve[]):Vector2[]; public addWrapPath(curve: Curve): void; public createGeometry(points: Vector3[]): Geometry; public createPointsGeometry(divisions: number): Geometry; public createSpacedPointsGeometry(divisions: number): Geometry; public add(curve: Curve): void; public closePath(): void; public getBoundingBox(): any; public getCurveLengths(): number; public getTransformedPoints(segments: number, bends?

友盟第三方分享时的注意事项(报40002错误)

//*******微信分享******** String appID = ""; String appSecret = ""; // 添加微信平台 UMWXHandler wxHandler = new UMWXHandler(this, appID, appSecret); wxHandler.addToSocialSDK(); //设置微信好友分享内容 WeiXinShareContent weixinContent = new WeiXinShareContent(); //设置分享文字 weixinContent.setShareContent(不能为空); //设置title weixinContent.setTitle(标题); //设置分享内容跳转URL weixinContent.setTargetUrl(跳转的网址); //设置分享图片 weixinContent.setShareImage(new UMImage(this, 图片地址));//若此处想填入http的网络图片地址,则weixinContent.setShareContent(不能为 空)中绝对不能为空,不然会报图片路径不合法40002 mController.setShareMedia(weixinContent); //*******微信朋友圈******** //*******QQ******** //*******QQ空间******** //*******新浪微博******** 此处只对微信进行了说明,其他分享同理

快速理解聚集索引和非聚集索引

数据库的索引,听起来挺神秘的,仔细想想。这些索引,其实就是平时咱们查东西时候常用的两种手段。无非就是为了提高我们找东西的效率而已。那么我们平时又是怎么查东西呢? 聚集索引: 聚集索引,来源于生活尝试。这中索引可以说是按照数据的物理存储进行划分的。对于一堆记录来说,使用聚集索引就是对这堆记录 进行 堆划分。即主要描述的是物理上的存储。 举个例子: 比如图书馆新进了一批书。那么这些书需要放到图书馆内。书如何放呢?一般都有一个规则,杂志类的放到101房间,文学类的放到102房间,理工类的放到103房间等等。这些存储的规则决定了每本书应该放到哪里。而这个例子中聚集索引为书的类别。 正式因为这种存储规则,才导致 聚集索引的唯一性。 误区: 有的人认为,聚集索引的字段是唯一的。这是因为sql server 中添加主键的时候,自动给主键所在的字段生成一个聚集索引。所以人们会认为聚集索引所加的字段是唯一的。 思考一下上面这个问题。杂志类的书放到101房间。那么如果杂志类的书太多,一个101房间存放不下。那么可能101,201两个房间来存放杂志类的书籍。如果这样分析的话,那么一个杂志类对应多个房间。放到表存储的话,那么这个类别字段 就不是唯一的了。 非聚集索引: 非聚集索引,也可以从生活中找到映射。非聚集索引强调的是逻辑分类。可以说是定义了一套存储规则,而需要有一块控件来维护这个规则,这个被称之为索引表。 继续使用上述提到的例子: 同学如果想去图书馆找一本书,而不知道这本书在哪里?那么这个同学首先应该找的就是 检索室吧。对于要查找一本书来说,在检索室查是一个非常快捷的的途径了吧。但是,在检索室中你查到了该书在XX室XX书架的信息。你的查询结束了吗?没有吧。你仅仅找到了目的书的位置信息,你还要去该位置去取书。 对于这种方式来说,你需要两个步骤: 1、查询该记录所在的位置。 2、通过该位置去取要找的记录。 区别: 聚集索引:可以帮助把很大的范围,迅速减小范围。但是查找该记录,就要从这个小范围中Scan了。 非聚集索引:把一个很大的范围,转换成一个小的地图。你需要在这个小地图中找你要寻找的信息的位置。然后通过这个位置,再去找你所需要的记录。 索引与主键的区别 主键:主键是唯一的,用于快速定位一条记录。 聚集索引:聚集索引也是唯一的。(因为聚集索引的划分依据是物理存储)。而聚集索引的主要是为了快速的缩小查找范围,即记录数目未定。 主键和索引没有关系。他们的用途相近。如果聚集索引加上唯一性约束之后,他们的作用就一样了。 使用场景 基于上述的两种规则,那么在什么时候适合聚集索引,什么时候适合非聚集索引? 如果你理解了数据库是如何使用索引的,那么你在看上一篇文章《高并发下update产生的死锁》就很容易明白了。

IOS中对于多个按钮,选中其中一个,其他按钮选中状态为NO

第一,定义一个全局的按钮变量 /** * 按钮选中,中间值 */ @property (nonatomic,strong) UIButton *selectedBtn; 第二,添加多个按钮到scrollView中 /** * 创建按钮添加到scrollView */ -(void)creatBtn { int i = 0; NSArray *titleArray = @[@"头条",@"热点",@"体育",@"北京",@"订阅",@"财经",@"科技",@"汽车",@"时尚",@"图片",@"跟帖",@"房产",@"直播",@"轻松一刻",@"军事",@"历史"]; for (NSString *title in titleArray) { UIButton *btn = [[UIButton alloc] init]; btn.frame = CGRectMake(i*pading + _tempW, 0, 50, 50); [btn setTitle:title forState:UIControlStateNormal]; btn.tag = i; btn.contentMode = UIViewContentModeCenter; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected]; [btn addTarget:self action:@selector(titleBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [btn sizeToFit]; _tempW += btn.

VS2010项目配置详解

首先看一下项目设置中可以使用的宏(环境变量),常用的有: ConfigurationName 配置名字,通常是Debug或者Release IntDir 编译器使用的中间目录,产出obj文件 OutDir 链接器使用的输出目录 ProjectDir 项目目录 ProjectName 项目名字 SolutionDir 解决方案目录 TargetDir 目标输出文件所在的目录 TargetExt 目标输出的扩展名 TargetFileName 目标输出文件名,包括扩展名 TargetName 目标输出名,不包括扩展名 TargetPath 目标输出文件的全路径名 下图是某一个工程所有设置的例子: 注意:从上图可以看出,TargetDir指目标目录,是一个目录。而TargetPath是目标路径,包括具体的文件名。 vs2010使用方案管理项目,一个解决方案下可包含多个项目。 默认情况下,项目属性的设置的目录起点为项目配置文件所在的位置,实际上就是项目头文件和源文件所在的位置。 vs2010中默认建立C++项目,则解决方案总目录下包含一个sln和一个项目文件夹,在vs2010编译器中生成debug和release解决方案后,总目录下还会生成对应的debug和release目录,存放最终生成的exe或dll文件,同时也会在项目文件夹下生成debug和release目录(存放的是中间编译文件obj)。 下面结合例子讲一下:solution为创建的解决方案,demo为创建的项目 解决方案solution总目录如下: 项目demo目录如下: 项目配置及系统变量关系: 在vs2010的项目属性页,会有一些系统变量,如下: SolutionDir:解决方案目录 Configuration:指debug或release ProjectName:项目名字 OutDir:在 常规--输出目录 中定义的值,如$(SolutionDir)$(Configuration)\,表示XXX\lolution\debug\目录值 IntDir:中间目录 TargetDir:生成exe或dll文件所在位置,如链接器-常规-输出文件为$(OutDir)$(TargetName)$(TargetExt)(即定义了exe输出位置,也就决定了TargetDit的值),此时TargetDir表示在XXX\lolution\debug\ TargetName:目标输出名,不包括扩展名 TargetPath:目标输出文件的全路径名 ProjectDir:表示项目目录值,一般在“调试-工作目录”中设置该值 TargetExt:扩展名 PlatformToolsetVersion: ConfigurationName:配置名字,通常是Debug或者Release 默认情况下“输出目录”和“输出文件”对应的目录值是一样的。 配置属性 常规 输出目录:$(SolutionDir)$(Configuration)\ //即 中间目录:$(Configuration)\ 目标文件名:$(ProjectName) 目标文件扩展名:.exe 生成日志文件:$(IntDir)\$(MSBuildProjectName).log 调试 命令:$(TargetPath),表示调试器要启动的exe全名,TargetPath就表示目标输出文件的全路径名,所以一般情况下它代表的值就等于“输出文件”属性代表的值 工作目录:$(ProjectDir) C/C++ 预编译头 预编译头输出文件:$(IntDir)$(TargetName).pch 输出文件 ASM列表位置:$(IntDir) 对象文件名:$(IntDir) 程序数据库文件名:$(IntDir)vc$(PlatformToolsetVersion).pdb 浏览信息 浏览信息文件:$(IntDir) 链接器

通过网卡获取IP真实地址信息

import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.List; import javax.servlet.http.HttpServletRequest; import com.quyougame.omp.sso.client.util.StringUtil; /** * ip地址处理工具 * @author Tseng 2015-9-10 * */ public class IPUtil { /** * 获取请求ip地址。 * * @param request * @return */ public static String getRemoteAdd(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.

超全!整理常用的iOS第三方资源

一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:hud提示框 地址:https://github.com/jdg/MBProgressHUD 3:XML/HTML解析 地址:https://github.com/topfunky/hpple 4:有文字输入时,能根据键盘是否弹出来调整自身显示内容的位置 地址:https://github.com/michaeltyson/TPKeyboardAvoiding 5:状态栏提示框 地址:https://github.com/jaydee3/JDStatusBarNotification 6:block工具包。将很多需要用delegate实现的方法整合成了block的形式 地址:https://github.com/zwaldowski/BlocksKit 7:图片加载 地址:https://github.com/rs/SDWebImage 8:正则表达式 地址:https://github.com/wezm/RegexKitLite 9:Masonry代码布局 地址:https://github.com/SnapKit/Masonry 10:弹出窗 地址:https://github.com/sberrevoets/SDCAlertView 11:Button的样式 地址:https://github.com/mattlawer/BButton 12:验证网络连接状态 地址:https://github.com/tonymillion/Reachability 13:自动计算表格行高 地址:https://github.com/forkingdog/UITableView-FDTemplateLayoutCell 14:动画效果的启动页 地址:https://github.com/IFTTT/JazzHands 15:iOS快速简单集成国内三大平台分享 地址:https://github.com/xumeng/XMShareModule 16:五项能力值展示的五边形 地址:https://github.com/dsxNiubility/SXFiveScoreShow 17:自动识别网址号码邮箱和表情的label 地址:https://github.com/molon/MLEmojiLabel 18:IM对话功能的封装 地址:https://github.com/ZhipingYang/UUChatTableView 19:字典转模型框架 地址:https://github.com/CoderMJLee/MJExtension 20:下拉上拉刷数据 地址:https://github.com/CoderMJLee/MJRefresh 21:表格行左右划动菜单 地址:https://github.com/MortimerGoro/MGSwipeTableCell 22:图文混搭 地址:https://github.com/zhouande/TLAttributedLabel 23:可以简单展示在UINavigationBar下方,类似Music app的播放列表视图,弹出菜单视图 地址:https://github.com/DrummerB/BFNavigationBarDrawer 24:比如筛选、模糊、优化、蒙版、调整大小、旋转以及保存等等。同时还提供了一个UIImageView子类从URL异步加载图片,并在下载完毕时展示图片。 地址:https://github.com/Nyx0uf/NYXImagesKit 25:底部TabBar 地址:https://github.com/robbdimitrov/RDVTabBarController 26:表情面版 地址:https://github.com/ayushgoel/AGEmojiKeyboard 27:记录框架 地址:https://github.com/CocoaLumberjack/CocoaLumberjack 28:IOS与javascript交互 地址:https://github.com/marcuswestin/WebViewJavascriptBridge 29:图表统计展示 地址:https://github.com/kevinzhow/PNChart 30:appStore评分 地址:https://github.com/arashpayan/appirater 31:iOS-Categories 扩展类大全 地址:https://github.com/shaojiankui/IOS-Categories 32:扫描二维码,仿微信效果,带有扫描条 地址:https://github.com/JxbSir/JxbScanQR 33:动效弹出视图(弹出窗里面为文字,可以定义弹出的方向,及显示的时间)--AMPopTip 地址:https://github.com/andreamazz/AMPopTip

Android WebView 开发 资源释放,处理详解

现在 app 与h5 结合的应用越来越多,这里我们一般用 WebView 来显示 但是 问题也挺多的,资源释放,缓存处理,等。 WebView 的基本使用 mWebview = (WebView) findViewById(R.id.webview); webview.loadUrl(""); </pre>WebView 的WebSettings 基本设置百度基本可以查到,我这里就贴出下<p></p><p></p><pre name="code" class="html"><span style="white-space:pre"> </span>setting.setAllowFileAccess(true); // 设置可以访问文件 setting.setBlockNetworkImage(false); // setting.setDomStorageEnabled(true); setting.setUseWideViewPort(true); setting.setLoadWithOverviewMode(true); // setting.setJavaScriptEnabled(true); setting.setDomStorageEnabled(true); setting.setJavaScriptEnabled(true); setting.setRenderPriority(RenderPriority.HIGH); if (AppUtils.isNetworkAvailable(mContext)) { setting.setCacheMode(WebSettings.LOAD_DEFAULT); // 设置 缓存模式 } else { setting.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 设置 // 缓存模式 } // 开启 DOM storage API 功能 // 开启 database storage API 功能 setting.setDatabaseEnabled(true); String cacheDirPath = getFilesDir().getAbsolutePath() + MyConfigurationConstant.APP_WEBVIEW; // String cacheDirPath = // getCacheDir().

C语言的指针大小问题

一说到指针的大小很多人都会想到int型,char型,double型,然后觉得不同类型的指针所占内存大小不同,其实这是一种误区. 因为指针其实就是一个无符号整形,一个整数而已,它的大小取决于你的系统是16 32 还是64位的 16/8=2byte 32/8=4byte 64/8=8byte . 但是你会问为什么我的系统是64位的,但是我的指针却是32位的4字节指针.这个也很简单解释,因为我们是用编译器来写代码的,编译器已经默认我们的程序是在32位系统下运行,所以我们在编译器当中看到的指针都是占4个字节. 有人又会问,为什么不用64位来编译呢?因为我们的程序要兼容32位的机器啊!你以为每个人都用64位的机器吗?? 讨论完指针大小问题,我们再讨论一下指针所指向的内存块所占内存大小.地球人 都知道char占一个字节,int占2个字节,double占4个字节,long double占8个字节(这是默认的32位编译环境下,在64位下翻倍就是了),所以一个char指针所占内存为4个字节(32位下),所指向的内存区域占1个字节.同理其它类型也是一样的, 最后附两张图: 32位下 64位下

你真的会使用XMLHttpRequest吗?

看到标题时,有些同学可能会想:“我已经用xhr成功地发过很多个Ajax请求了,对它的基本操作已经算挺熟练了。” 我之前的想法和你们一样,直到最近我使用xhr时踩了不少坑儿,我才突然发现其实自己并不够了解xhr,我知道的只是最最基本的使用。 于是我决定好好地研究一番xhr的真面目,可拜读了不少博客后都不甚满意,于是我决定认真阅读一遍W3C的XMLHttpRequest标准。看完标准后我如同醍醐灌顶一般,感觉到了从未有过的清澈。这篇文章就是参考W3C的XMLHttpRequest标准和结合一些实践验证总结而来的。 Ajax和XMLHttpRequest 我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是属于不同维度的2个概念。 以下是我认为对Ajax较为准确的解释:(摘自what is Ajax) AJAX stands for Asynchronous JavaScript and XML. AJAX is a new technique for creating better, faster, and more interactive web applications with the help of XML, HTML, CSS, and Java Script. AJAX is based on the following open standards: Browser-based presentation using HTML and Cascading Style Sheets (CSS). Data is stored in XML format and fetched from the server. Behind-the-scenes data fetches using XMLHttpRequest objects in the browser.

android gralloc 小结

从字面就可以看出来Gralloc接口是为了显示内存分配与释放 – Graphics Allocation。 它的主要目的有三个: Ø 为应用分配显示用内存; Ø 可以把显示内存在不同进程间进行映射; Ø 同步 通过加载gralloc抽象层(gralloc.xxx.so),可以打开fb设备(/dev/fb0)和gpu设备(/dev/graphic/), fb设备用于操作framebuffer,gpu设备负责图形缓冲区的分配和释放。 对于SurfaceFlinger服务端的本地窗口FramebufferNativeWindow将分别打开fb设备和gpu设备, FramebufferNativeWindow通过gpu设备从Framebuffer中分配图形缓冲区,可用来GPU render。 通过fb设备来分配framebuffer,可以显示经SurfaceFlinger混合后的图像。 是在FrameBufferNativeWindow的构造代码中,可以看到打开fb0设备获取Framebuffer Info,然后使用gralloc为该FrameBufferNativeWindow分配两个或者三个Framebuffer,即双缓冲或者三缓冲。 而对于应用程序端的SurfaceTextureClient本地窗口,其需要的图形缓冲区也是由SurfaceFlinger服务端来分配,应用程序进程只需要将服务端分配的图形缓冲区映射到应用程序的虚拟地址空间,图形缓冲区的映射过程也是由Gralloc模块完成。 gpu设备 Gpu打开过程就是创建并初始化一个gralloc_context_t对象,gpu负责图形buffer的分配和释放。 fb设备 Fb设备打开过程就是创建并初始化一个fb_context_t对象,关于屏幕大小、格式、刷新频率等信息都是通过Framebuffer驱动来获取,最后将Framebuffer映射到SurfaceFlinger进程地址空间,并将映射后的首地址保持到private_module_t的framebuffer->base变量中。 可以认为Gralloc module中有两个设备gpu_alloc_device和fb_device,前者用于分配GPU0使用的内存和FB内存,GPU0内存管理使用ION allocator;后者用于获取分配Framebuffer Info并操作fb。 注意,在Android系统中,在系统帧缓冲区中分配的图形缓冲区是在SurfaceFlinger服务中使用的, 而在内存中分配的图形缓冲区既可以在SurfaceFlinger服务中使用,也可以在其它的应用程序中使用。 当其它的应用程序需要使用图形缓冲区的时候,它们就会请求SurfaceFlinger服务为它们分配。 因此,对于其它的应用程序来说,它们只需要将SurfaceFlinger服务返回来的图形缓冲区映射到自己的进程地址空间来使用就可以了。 下面是分配内存最核心的函数: static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride) { if (!pHandle || !pStride) return -EINVAL; size_t size, stride; int align = 4; int bpp = 0; switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: bpp = 4; break; case HAL_PIXEL_FORMAT_RGB_888: bpp = 3; break; case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_RAW_SENSOR: bpp = 2; break; default: return -EINVAL; } size_t bpr = (w*bpp + (align-1)) & ~(align-1); size = bpr * h; stride = bpr / bpp; int err; if (usage & GRALLOC_USAGE_HW_FB) { err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); //申请图形缓冲区,用来render } else { err = gralloc_alloc_buffer(dev, size, usage, pHandle); //申请帧缓冲区,用来显示 } if (err < 0) { return err; } *pStride = stride; return 0; } 在申请gralloc的时候,下面的enum表示要申请的buffer的用途 { /* buffer is never read in software */ GRALLOC_USAGE_SW_READ_NEVER = 0x00000000, /* buffer is rarely read in software */ GRALLOC_USAGE_SW_READ_RARELY = 0x00000002, /* buffer is often read in software */ GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003, /* mask for the software read values */ GRALLOC_USAGE_SW_READ_MASK = 0x0000000F, /* buffer is never written in software */ GRALLOC_USAGE_SW_WRITE_NEVER = 0x00000000, /* buffer is rarely written in software */ GRALLOC_USAGE_SW_WRITE_RARELY = 0x00000020, /* buffer is often written in software */ GRALLOC_USAGE_SW_WRITE_OFTEN = 0x00000030, /* mask for the software write values */ GRALLOC_USAGE_SW_WRITE_MASK = 0x000000F0, /* buffer will be used as an OpenGL ES texture */ GRALLOC_USAGE_HW_TEXTURE = 0x00000100, /* buffer will be used as an OpenGL ES render target */ GRALLOC_USAGE_HW_RENDER = 0x00000200, /* buffer will be used by the 2D hardware blitter */ GRALLOC_USAGE_HW_2D = 0x00000400, /* buffer will be used by the HWComposer HAL module */ GRALLOC_USAGE_HW_COMPOSER = 0x00000800, /* buffer will be used with the framebuffer device */ GRALLOC_USAGE_HW_FB = 0x00001000, /* buffer will be used with the HW video encoder */ GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000, /* buffer will be written by the HW camera pipeline */ GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000, /* buffer will be read by the HW camera pipeline */ GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000, /* buffer will be used as part of zero-shutter-lag queue */ GRALLOC_USAGE_HW_CAMERA_ZSL = 0x00060000, /* mask for the camera access values */ GRALLOC_USAGE_HW_CAMERA_MASK = 0x00060000, /* mask for the software usage bit-mask */ GRALLOC_USAGE_HW_MASK = 0x00071F00, /* buffer will be used as a RenderScript Allocation */ GRALLOC_USAGE_RENDERSCRIPT = 0x00100000, GRALLOC_USAGE_HW_FIMC1 = 0x01000000, GRALLOC_USAGE_HW_ION = 0x02000000, GRALLOC_USAGE_YUV_ADDR = 0x04000000, /* SEC Private usage , for Overlay path at HWC */ GRALLOC_USAGE_HWC_HWOVERLAY = 0x20000000, /* buffer should be displayed full-screen on an external display when * possible */ GRALLOC_USAGE_EXTERNAL_DISP = 0x00002000, /* Must have a hardware-protected path to external display sink for * this buffer.

android hwcomposer 在视频播放中的应用

之前写了一篇博客,分析了视频如何显示的 http://blog.csdn.net/wan8180192/article/details/50269405 以及gralloc的内存管理 http://blog.csdn.net/wan8180192/article/details/50513895 这里结合hwcomposer模块,以及视频播放的场景,对其中有一些细节,在这里再做补充一下 。 android中,多个surface layer要显示到屏幕上,就要合成到一起,合成方式有两种: 离线合成 先将所有图层画到一个最终层(FrameBuffer)上,再将FrameBuffer送到LCD显示。由于合成FrameBuffer与送LCD显示一般是异步的(线下生成FrameBuffer,需要时线上的LCD去取),因此叫离线合成。 在线合成 不使用FrameBuffer,在LCD需要显示某一行的像素时,用显示控制器将所有图层与该行相关的数据取出,合成一行像素送过去。只有一个图层时,又叫Overlay技术。 由于省去合成FrameBuffer时读图层,写FrameBuffer的步骤,大幅降低了内存传输量,减少了功耗,但这个需要硬件支持。 对于这两种方式,各有优缺点, 离线合成充分利用GPU,更加灵活,不受win layer数量限制。但是功耗大,不利于移动设备。GPU如果性能不强,复杂应用场景下会出现卡顿,实时性不好 在线合成,功耗小,没有性能瓶颈,没有时延。但是不够灵活。UI layer一旦变多,需要重新借助于GPU的离线合成。 一般来说,优先使用overlay.实在不行就用GPU 在实际代码中,可以看到SurfaceFlinger::doComposeSurfaces中, 有以下处理, switch (cur->getCompositionType()) { case HWC_OVERLAY: { overlay 方式,采用HWC硬件来合成 const Layer::State& state(layer->getDrawingState()); if ((cur->getHints() & HWC_HINT_CLEAR_FB) && i && layer->isOpaque() && (state.alpha == 0xFF) && hasGlesComposition) { // never clear the very first layer since we're // guaranteed the FB is already cleared layer->clearWithOpenGL(hw, clip); } break; } case HWC_FRAMEBUFFER: { ///非overlay方式,采用GPU来合成,后续调用的是openGL layer->draw(hw, clip); break; } case HWC_FRAMEBUFFER_TARGET: { /异常处理。FRAMEBUFFER_TARGET不应该出现在这个流程里。FRAMEBUFFER_TARGET是合成是使用的目标buffer。 // this should not happen as the iterator shouldn't // let us get there.

android 显示系统初步总结

最近研究了一下android的显示系统,参考了一些文档,做一点简单的总结 1,废话不多说,先来一张 surfacefinger源码的source tree 2,再上一张surfacefinger的组件图。(硬件平台是exynos CPU + MALI GPU) 3,名词解释 UMP : unified memory provider 这是由ARM定义的一种内存管理方式,主要用在Mali GPU 允许同一段内存被不同的进程空间映射。 这样可以共享内存,避免了内存的拷贝 最显著的应用,就是视频播放: OMX进程把解码后的数据放入到一段内存,surfacefilnger进程也共享这段内存,从而把这段内存的YUV数据,作为 openGL的纹理进行渲染 SMM: share memory management fbdev: framebufer driver off-screen buffers: 由app或者GPU在绘画的buffer,暂时还没有送到屏幕上 参考:http://blog.csdn.net/wan8180192/article/details/50269405 on-screen buffers: 数据就绪,可以直接拿来显示的buffer 参考:http://blog.csdn.net/wan8180192/article/details/50719123 4,介绍一下几个底层模块 4.1 gralloc gralloc是surfaceflinger向底层申请和维护graphic buffer的接口 使用共享内存来申请off-screen buffers 使用framebuffer内存来申请on-screen buffers 通过usage flag来设置buffer类型,例如GRALLOC_USAGE_HW_FB,GRALLOC_USAGE_HW_COMPOSER gralloc也是surfaceflinger设置屏幕显示需要的物理参数的接口 初始化framebuffer 驱动的配置,例如colour depth, double buffering,screen size, double buffering场景下,需要负责交换on-screen buffers 采用HWComposer类的形式体现给surfaceflinger,供上层使用 4.2 hwcomposer hwcomposer负责为surfaceflinger提供接口,来讲off-screen buffers中的内容,组合到on-screen buffers 采用HWComposer类的形式体现给surfaceflinger,供上层使用 能够声明自己的API版本号,这样上层就知道他的 capability 能够与gralloc互相交互,来访问off-screen buffers ,on-screen buffers hwcomposer API capability 表格如下

noi 2729:Blah数集——单调队列

2729:Blah数集 Description 大数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下: (1) a是集合Ba的基,且a是Ba的第一个元素; (2)如果x在集合Ba中,则2x+1和3x+1也都在集合Ba中; (3)没有其他元素在集合Ba中了。 现在小高斯想知道如果将集合Ba中元素按照升序排列,第N个元素会是多少? Input 输入包括很多行,每行输入包括两个数字,集合的基a(1<=a<=50))以及所求元素序号n(1<=n<=1000000) Output 对于每个输入,输出集合Ba的第n个元素值 Sample Input 1 100 28 5437 Sample Output 418 900585 题目分析:本来想着要省事,用优先队列吧,虽然知道n=10^6 ,优先队列nlong(n)要超时,还是想随便写写,看过几个点,结果一个也不过。 本题要要递增的数列,所以用单调队列。定义两个队头指针,head2,head3分别代表2*x+1,3*x+1;比较head2和head3,谁小谁入队列,入队列后指针后移,如果相等,只入一次,两个指针都后移。0(n)的做法,本来要800多ms,用位运算后能到500多Ms。 程序 #include<iostream> #include<cstdio> using namespace std; long long q[1000010]; long long a,n,head2,head3,tail; void work(){ head2=1;//2*x+1; head3=1;//3*x+1; tail=1; q[1]=a; while(tail<n){ long long t1=(q[head2]<<1)+1, t2=(q[head3]<<1)+q[head3]+1; if(t1<t2){ //2*q[head2]+1<3q[head3 ] +1 q[++tail]=t1; head2++; } else{ if(t1>t2){ q[++tail]=t2; head3++; } else{//相等,重复的数,只进一次栈 q[++tail]=t1; head3++; head2++; } } } printf("%d\n",q[tail]); }

[消息传递之五]-NSMatchPort练习

#import <UIKit/UIKit.h> @interface ViewController : UIViewController<NSMachPortDelegate> @property (nonatomic) NSMutableArray* NotArray; @property (nonatomic) NSLock* NotLock; @property (nonatomic) NSMachPort* NotPort; @end #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.NotArray = [[NSMutableArray alloc] init]; self.NotLock = [[NSLock alloc] init]; self.NotPort = [[NSMachPort alloc] init]; self.NotPort.delegate = self; //注意点1:kCFRunLoopCommonModes 将输入源加入此模式意味着在Common Modes中包含的所有模式下都可以处理 //注意点2:NSRunLoop主要是用于oc程序,而CFRunLoop主要用于C/C++程序,这是因为C/C++程序无法使用oc对象而创建的一个类 //注意点3:所有线程都自动创建一个RunLoop, 在线程内通过 [NSRunLoop currentRunLoop] 获得当前线程的RunLoop. [[NSRunLoop currentRunLoop] addPort:self.NotPort forMode:NSDefaultRunLoopMode]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ProcessNotification:) name:@"ObserverName" object:nil]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSMutableDictionary* dic = [[NSMutableDictionary alloc] init]; [dic setObject:[NSNumber numberWithInteger:80] forKey:@"

Javascript判断一个数字是否在一个区间内

<script> //参数str判断的字符串 m最小值 n最大值 function check(str,m,n){ var re = /(\d+)/g; while(re.exec(str)) { var int = parseInt(RegExp.$1); if(int <m || int> n)return false; } return true; } </script> <input name="t1" type="text" id="t1" οnblur="Check(this)">

Android 经典蓝牙用法

概述: Android平台包括了对蓝牙网络协议栈的支持, 它让设备可以跟其它蓝牙设备实现无线数据交换. 应用框架通过Android Bluetooth API提供了访问蓝牙的功能. 这些API可以让APP无线连接到其它的蓝牙设备, 可以使用点对点和多点无线功能. 通过使用蓝牙API, 一个Android APP可以实现这些功能: l 扫描其它的蓝牙设备 l 为配对的蓝牙设备查询本地蓝牙适配器 l 建立RFCOMM通道 l 通过”服务发现”连接到其它设备 l 与其它设备交换数据 l 管理多连接 本文描述了如何使用经典蓝牙. 经典蓝牙是电池密集型操作的正确选择, 比如流和Android设备之间通信. 为了实现蓝牙设备低耗电的需求, Android4.3引入了支持Bluetooth Low Energy的API. 该功能可以参考这里. 将在下一篇blog中介绍. 基础: 该文档描述了如何使用Android Bluetooth API来完成四种使用蓝牙通信的主要任务: 设置蓝牙, 在本地区域搜索配对或者可用的设备, 连接设备, 和设备间交换数据. 所有Bluetooth API都在android.bluetooth包中. 这里列举了包中我们需要用到的类和接口的总览: 1. BluetoothAdapter: 代表本地蓝牙适配器(蓝牙无线电(radio)).BluetoothAdapter是蓝牙交互的入口. 通过它我们可以发现其它的蓝牙设备, 查询配对设备的列表, 使用一个已知的MAC地址实例化一个BluetoothDevice, 还可以创建一个BluetoothServerSocket来监听其它设备发来的通信. 2. BluetoothDevice: 表示一个远程的蓝牙设备. 使用它可以请求一个与远程设备通过BluetoothSocket建立的链接, 或者用来查询设备的相关信息, 比如名字, 地址, 类, 和配对状态. 3. BluetoothSocket: 表示为蓝牙socket的接口(类似于TCPSocket). 它是一个连接点, 允许一个APP跟其它的蓝牙设备通过InputStream和OutputStream来交换数据. 4. BluetoothServerSocket: 代表一个开放的服务器socket,它持续的监听连接进来的需求(类似于一个TCP ServerSocket). 为了连接两个Android设备, 一个设备必须用该类开启一个服务器socket.

不显示 Flask Server 的输出信息

from flask import Flask app = Flask(__name__) import logging log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run()

Ubuntu在vmware虚拟机无法上网的解决方法

在vmware中安装Ubuntu之后,我们希望基本的功能如上网、传输文件等功能都是可用的,但是经常遇到不能上网的情况。使用笔记本时,我们经常希望能通过无线网卡上网,但是在做嵌入式开发时,我们还希望虚拟机能通过有线网连接到嵌入式设备上。如何保证两者快速切换,有时候会很头疼。 在网上查阅相关资料和自己试验后,这里给出一种方便的解决不能上网问题的方法。 首先,检查你的虚拟机是否开启了网络服务,检查方法是打开控制面板->-管理工具--->服务 ,查找 VMware DHCP Service 和VMware NAT Service ,保证这两个服务已经启动。如果没有禁用,则要先将其开启,一般设置为自动启动就可以 ,如果设置不成功,可以先将虚拟机关掉,然后重装一次vmare或者重启电脑试一下。 第二,设置网络类型,一般在vmare中有四种。 第一种: Bridged: Connected directly to the physical network,使用桥接网卡(VMnet0虚拟网卡),表示当前虚拟机与主机(指运行VMware Workstation软件的计算机)在同一个网络中。第二种:NAT: Used to share the host's IP address,使用NAT网卡(VMnet8虚拟网卡),表示虚拟机通过主机单向访问主机及主机之外的网络,主机之外的网络中的计算机,不能访问该虚拟机。第三种: Host-only: A private network shared with the host,只使用本地网络(VMnet1虚拟网卡),表示虚拟机只能访问主机及所有使用VMnet1虚拟网卡的虚拟机。主机之外的网络中的计算机不能访问该虚拟机,也不能被该虚拟机所访问。第四种: Custom: Specific virtual network,没有网络连接,表明该虚拟机与主机没有网络连接。 我们一般使用前两种多一些,如果不知道怎么设置,优先采用桥接模式,并且选中“复制物理网络属性”。 第三,设置虚拟机网络编辑器。在虚拟机的左上方,选中“虚拟网络编辑器”,这里的操作需要使用管理员权限。根据右下方的提示,单击“更改设置”。 之后,网络编辑器会自动重启一次,重启完后会多出来一项。重启完的截图如下所示: 在桥架模式下,这里可以设置桥接所使用的网卡。如果想通过无线网卡上网, 则这里要选中无线网卡对应的虚拟网桥。 设置完毕后,在虚拟机里采用自动获取网络地址的方式即可上网,如果自己手动设置,有时候然而上不了。 如果要让虚拟机可以通过有线网络连接到嵌入式开发板中 ,这里要再改回去。比较麻烦一些。这一点vmare就不如vbox方便,vbox可以自动搜索,不需要频繁的手动设置。

利用ajax向控制器中传二维数组

使用ajax向控制器中传递字符串或者值的时候,我们就按照平常的传值进行, 但是在传递数组的时候要特别注意,它不支持传递关联数组, 不过要想传递过去还是可以得,就是把它做下处理,json_encode()一下,并且传递过去之后还是原来的数组格式 但是大数组就不要传了,比较耗费资源,直接把需要的参数传过去,到控制器中再进行相关处理

树形DP总结,持续更新

自己做了动态规划的题目已经有了一个月,但是成效甚微,所以来总结一下动态规划,希望自己能够温故知新。这个博客是关于树形dp的,动态规划的一类题目。 首先从最简单的树形DP入手,树形DP顾名思义就是一棵树和动态规划结合起来,我做了7,8题树形DP,目前为止发现树形DP的代码样式都是差不多,都在dfs树的过程中进行DP。 首先看一道简单的入门题目 题意就是在一棵树中,选取一些结点每个结点都可以监管者连接自己的一条边,问最少选取多少个结点可以让所有边都被监管起来。 思路:1:结点状态可以分为取和不取,所以用二维数组表示结点的状态。2:如果当前结点选取了,子结点可以选取也可以不选取,但是如果当前结点没有选取,那么子节点必须选取。 状态转移方程见代码里 #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <stdlib.h> using namespace std; #define MAX 1500 int n; int root; int tot; struct Node { int value; int next; }edge[MAX*2+5]; int head[MAX+5]; int dp[MAX+5][2]; int vis[MAX+5]; void add(int x,int y) { edge[tot].value=y; edge[tot].next=head[x]; head[x]=tot++; } void dfs(int root) { dp[root][0]=0; dp[root][1]=1; vis[root]=1; for(int i=head[root];i!=-1;i=edge[i].next) { int k=edge[i].value; if(!vis[k]) { dfs(k); //状态转移方程 dp[root][0]+=dp[k][1]; dp[root][1]+=min(dp[k][0],dp[k][1]); } } } int main() { int a,b; int m; while(scanf("

C语言劫持

劫持打开计算器 #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<string.h> #include"detours.h" #pragma comment(lib,"detours.lib") //劫持自己 static int (*oldsystem)(const char * _Command) = system;//创建函数指针等于地址 int newsystem(const char * _Command) //新的函数禁止做东西 { printf("%s",_Command); return 0; } int newsystemA(const char * _Command) //新的函数过滤 { char *p=strstr(_Command,"tasklist"); if(p==NULL) { oldsystem(_Command); }else { printf("%s禁止执行",_Command); return 0; } return 0; } //开始拦截 void Hook() { DetourRestoreAfterWith();//恢复原来状态, DetourTransactionBegin();//拦截开始 DetourUpdateThread(GetCurrentThread());//刷新当前线程 //这里可以连续多次调用DetourAttach,表明HOOK多个函数 DetourAttach((void **)&oldsystem, newsystemA);//实现函数拦截 DetourTransactionCommit();//拦截生效a } //取消拦截 void UnHook() { DetourTransactionBegin();//拦截开始 DetourUpdateThread(GetCurrentThread());//刷新当前线程 //这里可以连续多次调用DetourDetach,表明撤销多个函数HOOK DetourDetach((void **)&oldsystem, newsystemA); //撤销拦截函数 DetourTransactionCommit();//拦截生效 } void main() { system("

挂载3T移动硬盘(已解决)

目的:想用一个3T的外置硬盘存储数据, ubuntu和windows都能使用。 发现一堆问题。 1,windows下默认是2T,分完区后剩下700多兆不能用。 2,linux下挂载磁盘提示错误 NTFS signature is missing. 第一次使用3T硬盘,发现问题多多。 1,MBR分区最大只支持2T,3T的话,要改成GPT分区。于是改成了GPT的分区。 2,发现GTP分区支持NTFS,于是很高兴的分完区去ubuntu下面挂载。 3,结果问题来了,发现一台机器上使用fdisk 发现提示 NTFS signature is missing。 4,百度了一下,度娘说大于2T时候不能用fdisk,可以用parted,但fdisk可以显示,就先用他了。于是去找 NTFS signature is missing的问题。 5,找了半天。终于有点线索,应该是分区有问题。http://forum.kodi.tv/showthread.php?tid=159410 6,于是用winpe启动机器,用diskgenius看了一下磁盘。果然磁盘下有2个分区。果断删掉。然后只分一个区。 7,再次挂盘,发现问题不存在了

webView后台播放音乐不能关闭的解决办法

项目中有一个活动页面,进入就需要播放音乐,而且不需要用户点击 webView.mediaPlaybackRequiresUserAction = NO; webView不需要用户触发,播放音频的时候。退出界面,音乐会持续播放。 一开始想到的解决方式 (1).注销webView,不好用。 (2).[webView reload]多次点击进入webView会出现多个音乐重复播放的问题。 (3).[self.hdWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@”about:blank”]]]; load一个空的page。会出现的问题是,如果在webView push一个原生的界面,返回的时候canGoback会回到一个空的page (4).关闭界面的时候,调用js的方法。会出现问题同第二个,多次播放的问题 // JSValue *JSfunc =_jsContext[@”guanbiyinyue”]; // [JSfunc callWithArguments:nil]; 真正的解决方式!!!!! load 一个空,不是page -(void)viewWillDisappear:(BOOL)animated{ // [_hdWebView stopLoading]; // JSValue *JSfunc =_jsContext[@”guanbiyinyue”]; // [JSfunc callWithArguments:nil]; [self.hdWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@”“]]]; }

windows下用sendmail配置php的mail函数

php自带的mail函数,由于使用无验证的smtp服务,大部分服务商已不支持,解决办法有两个: 一是自己搭建smtp服务器; 二是使用第三方smtp服务器和新的sendmail函数,使用第二种方法: 1、首先去http://glob.com.au/sendmail/下载sendmail.zip 2、解压sendmail.zip到某个文件夹下,比如D:\sendmail\,路径一定要短!!!否则会出bug!!! 3、配置php.ini 找到[mail function]部分,只留下下面两句话,其他注释掉 sendmail_path = "D:\sendmail\sendmail.exe -t" //将mail函数路径定义到自己的sendmail函数上 mail.add_x_header = On 4、配置sendmail.ini smtp_server=smtp.163.com //或其他smtp服务器,有可能需要用户开通smtp服务 smtp_port=25 auth_username=xxx@xxx.com //用户名 auth_password=xxxxxxxx //密码 5、重启Apache服务器,使用mail函数就可以发送成功啦

找出重复元素并计算次数

比如10个数字 1 3 2 5 3 4 7 3 5 2 找出哪些是重复的并且重复了几次 Integer[] arr = new Integer[]{1,3,2,5,3,4,7,3,5,2}; Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Integer i : arr) { if(map.get(i)!=null){ map.put(i, map.get(i)+1); }else{ map.put(i, 1); } } for(Entry<Integer,Integer> entry :map.entrySet()){ if(entry.getValue()>1){ System.out.println("数字:"+entry.getKey()+";次数:"+entry.getValue()); } }把这些数据放到map中为Key,默认value为1,遍历数组当map.get(key) !=null; 说明该元素重复了,就把value+1; 这样map中Key就是这个数组中没有重复的数,而对应的value就是该值的重复次数

峰值的部分计算方法

1) 二八法 若80%的访问量集中在20%的时间里,可用此分析方法,其图形就是一个正态分布图,如下。 具体计算公式为: tps = (24小时的PV值*80%)/(24*3600*20%) 举例有,假如中文站每日的访问量为500万,其中19:00-23:40,访问量为400万,其余时间段的访问量很平坦,而且其余时间段的总访问量为100万,那么就可以用二八法,其计算公式为 tps = (500万*0.8)/(24*3600*0.2)。 2)简单峰值法 若在每天的某一时段里有很大的访问量,其他时间相对较少,可以用简单峰值法,其实二八法只是简单峰值法的一个特例。 具体计算公式为: tps =(24小时的PV值)/(峰值时间段中的小时数*3600) 举例有,假如中文站每日的访问量为500万,其中17:00-24:00这个时间段里面访问量为450万,其他时间段的访问量很平缓,那么,我可以用简单峰值法近似计算,其计算公式为 tps = 500万/((24-17)*3600) 3)无峰值法 若24小时里的访问量都是平稳波动的,没有峰值,那么可以采用无峰值计算方法,图形如下。 具体计算公式为: tps= (24小时的PV值)/(24*3600) 举例有,假如中文站每日的访问量为500万,每小时的访问量都为20万左右,那么,可以用无峰值法来近似计算,其计算公式为 tps = 500万/(24*3600)。 

35 个 Java 代码性能优化总结

前言 代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是,吃的小虾米一多之后,鲸鱼就被喂饱了。代码优化也是一样,如果项目着眼于尽快无BUG上线,那么此时可以抓大放小,代码的细节可以不精打细磨;但是如果有足够的时间开发、维护代码,这时候就必须考虑每个可以优化的细节了,一个一个细小的优化点累积起来,对于代码的运行效率绝对是有提升的。 代码优化的目标是: 1、减小代码的体积 2、提高代码运行的效率 代码优化细节 1、尽量指定类、方法的final修饰符 带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的。为类指定final修饰符可以让类不可以被继承,为方法指定final修饰符可以让方法不可以被重写。如果指定了一个类为final,则该类所有的方法都是final的。Java编译器会寻找机会内联所有的final方法,内联对于提升Java运行效率作用重大,具体参见Java运行期优化。此举能够使性能平均提高50%。 2、尽量重用对象 特别是String对象的使用,出现字符串连接时应该使用StringBuilder/StringBuffer代替。由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理,因此,生成过多的对象将会给程序的性能带来很大的影响。 3、尽可能使用局部变量 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快,其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收。 4、及时关闭流 Java编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。 5、尽量减少对变量的重复计算 明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作: for (int i = 0; i < list.size(); i++) {...} 建议替换为: for (int i = 0, int length = list.size(); i < length; i++) {...} 这样,在list.size()很大的时候,就减少了很多的消耗 6、尽量采用懒加载的策略,即在需要的时候才创建 例如: String str = "aaa";if (i == 1) { list.add(str); } 建议替换为: if (i == 1) { String str = "aaa"; list.add(str); } 7、慎用异常 异常对性能不利。抛出异常首先要创建一个新的对象,Throwable接口的构造函数调用名为fillInStackTrace()的本地同步方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,Java虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制程序流程。 8、不要在循环中使用try…catch…,应该把其放在最外层

面试题_103_to_124_关于 OOP 和设计模式的面试题

这部分包含 Java 面试过程中关于 SOLID 的设计原则,OOP 基础,如类,对象,接口,继承,多态,封装,抽象以及更高级的一些概念,如组合、聚合及关联。也包含了 GOF 设计模式的问题。 103)接口是什么?为什么要使用接口而不是直接使用具体类? 接口用于定义 API。它定义了类必须得遵循的规则。同时,它提供了一种抽象,因为客户端只使用接口,这样可以有多重实现,如 List 接口,你可以使用可随机访问的 ArrayList,也可以使用方便插入和删除的 LinkedList。接口中不允许写代码,以此来保证抽象,但是 Java 8 中你可以在接口声明静态的默认方法,这种方法是具体的。 104)Java 中,抽象类与接口之间有什么不同?(答案) Java 中,抽象类和接口有很多不同之处,但是最重要的一个是 Java 中限制一个类只能继承一个类,但是可以实现多个接口。抽象类可以很好的定义一个家族类的默认行为,而接口能更好的定义类型,有助于后面实现多态机制。关于这个问题的讨论请查看答案。 105)除了单例模式,你在生产环境中还用过什么设计模式? 这需要根据你的经验来回答。一般情况下,你可以说依赖注入,工厂模式,装饰模式或者观察者模式,随意选择你使用过的一种即可。不过你要准备回答接下的基于你选择的模式的问题。 106)你能解释一下里氏替换原则吗?(答案) 107) 什么情况下会违反迪米特法则?为什么会有这个问题?(答案) 迪米特法则建议“只和朋友说话,不要陌生人说话”,以此来减少类之间的耦合。 108)适配器模式是什么?什么时候使用? 适配器模式提供对接口的转换。如果你的客户端使用某些接口,但是你有另外一些接口,你就可以写一个适配去来连接这些接口。 109)什么是“依赖注入”和“控制反转”?为什么有人使用?(答案) 110)抽象类是什么?它与接口有什么区别?你为什么要使用过抽象类?(答案) 111)构造器注入和 setter 依赖注入,那种方式更好?(答案) 每种方式都有它的缺点和优点。构造器注入保证所有的注入都被初始化,但是 setter 注入提供更好的灵活性来设置可选依赖。如果使用 XML 来描述依赖,Setter 注入的可读写会更强。经验法则是强制依赖使用构造器注入,可选依赖使用 setter 注入。 112)依赖注入和工程模式之间有什么不同?(答案) 虽然两种模式都是将对象的创建从应用的逻辑中分离,但是依赖注入比工程模式更清晰。通过依赖注入,你的类就是 POJO,它只知道依赖而不关心它们怎么获取。使用工厂模式,你的类需要通过工厂来获取依赖。因此,使用 DI 会比使用工厂模式更容易测试。关于这个话题的更详细讨论请参见答案。 113)适配器模式和装饰器模式有什么区别?(答案) 虽然适配器模式和装饰器模式的结构类似,但是每种模式的出现意图不同。适配器模式被用于桥接两个接口,而装饰模式的目的是在不修改类的情况下给类增加新的功能。 114)适配器模式和代理模式之前有什么不同?(答案) 这个问题与前面的类似,适配器模式和代理模式的区别在于他们的意图不同。由于适配器模式和代理模式都是封装真正执行动作的类,因此结构是一致的,但是适配器模式用于接口之间的转换,而代理模式则是增加一个额外的中间层,以便支持分配、控制或智能访问。 115)什么是模板方法模式?(答案) 模板方法提供算法的框架,你可以自己去配置或定义步骤。例如,你可以将排序算法看做是一个模板。它定义了排序的步骤,但是具体的比较,可以使用 Comparable 或者其语言中类似东西,具体策略由你去配置。列出算法概要的方法就是众所周知的模板方法。 116)什么时候使用访问者模式?(答案) 访问者模式用于解决在类的继承层次上增加操作,但是不直接与之关联。这种模式采用双派发的形式来增加中间层。 117)什么时候使用组合模式?(答案) 组合模式使用树结构来展示部分与整体继承关系。它允许客户端采用统一的形式来对待单个对象和对象容器。当你想要展示对象这种部分与整体的继承关系时采用组合模式。 118)继承和组合之间有什么不同?(答案) 虽然两种都可以实现代码复用,但是组合比继承共灵活,因为组合允许你在运行时选择不同的实现。用组合实现的代码也比继承测试起来更加简单。 119)描述 Java 中的重载和重写?(答案) 重载和重写都允许你用相同的名称来实现不同的功能,但是重载是编译时活动,而重写是运行时活动。你可以在同一个类中重载方法,但是只能在子类中重写方法。重写必须要有继承。 120)Java 中,嵌套公共静态类与顶级类有什么不同?(答案)

https原理浅析

之前一直对于https原理比较迷惑,只是知道是http的安全版,花了些时间学习,发现讲解https的博客有很多,但是知识点比较散乱,不成系统。这里列举下我对https的认识,有错误希望支持。 hash算法 Hash算法是一种单向算法,可以对目标信息进行加密生成一段特定长度的Hash值,但反过来却不能对这个Hash值进行反向运算得到目标信息。即使修改文本的一个字节,采用hash算法hash值会有很大不同。Hash算法常用于信息完整性和可信性的校验。 举个例子: 例如tomcat官网[http://tomcat.apache.org/download-native.cgi],展示了每个现在文件的采用不同hash算法得到的hash值,如果一个用户下载了对应的安装包,那怎么取验证该安装包是否被篡改呢?将该安装包采用每一种hash算法计算该文件的hash值然后与官网比对,如果不一致,代表该文件被第三方篡改了。常用的有MD5,SHA等加密算法。 加密算法 加密算法分成对称加密和非对称加密 对称加密: 加密和解密使用相同的秘钥,优点加密算法简单快速,缺点双方共享同一个秘钥,技能加密也能解密,安全性较差。常用的加密算法有DES,AES等算法 非对称加密:加密和解密使用不同秘钥,加密采用私钥,解密使用公钥。优点私钥自己保管,公钥可以随意对外公开。非对称加密最常见的就是RSA加密算法。 采用http有哪些不好? http最大的隐患是用户的信息在公网中都是采用明文传输的,想象下我们的支付宝账号和密码如果是明文传输,万一在运营上某个路由器上被黑客劫持怎么办,就好比“出门没有穿裤子” 另外http在公网中明文传输,网络运营商加点内容(比如广告)易如反掌。 https工作原理 浏览器将自己支持的一套加密规则(包括加密算法和hash算法)发送给网站。网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。获得网站证书之后浏览器要做以下工作: 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。网站接收浏览器发来的数据之后要做以下的操作: 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。使用密码加密一段握手消息,发送给浏览器。浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。 有了对称加密的秘钥,也就是上面的随机密码 再采用约定好的对称加密算法,就可以安全的传输用户名和密码了。 https是不是一定安全呢? 假如客户端在上述步骤1中,请求被拦截,发送到一个坏的黑客服务器中了呢?假如黑客服务器按照上面相同的方法跟客户端进行https安全握手,那岂不是照样不安全吗? 要解决这个问题,关键在上面第3步中第1)小部,验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),这个就是CA(第三方可行机构),如果要发布一个服务采用https,大公司都会想CA购买证书,CA机构颁发的证书非常昂贵。如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。 如果浏览器提示了证书不受信任,用户仍然点击确认,是一个安全网站还好,如果是一个钓鱼网站就怪不了别人了。