IOS 如何通过浏览器打开App

前言: 随着App的开发,花样也越来越多了。现如今,是一个商家猖獗的时代,处处都是他们投放的广告。广泛的推广他们的产品或者服务,他们就在网上投放大量的网页,其中网页里面有一些特殊或者炫彩的按钮,或者文字。当浏览用户点击他们,他们就会进入这个商家的App里面,打开商家指定的页面。如果没有安装商家的App.他们提示您,去相应的位置下载他们的App。那么如何从网页调起您的App呢? 第一步:配置您的App。 1、我们要到您的App。(我找的App如下) 2、打开 看美App的开发项目的 info.plist 页面,并按图设置。(如下:图) 第二:我们编写 HTML 网页模拟商家网页。 1、网页内容代码 <!DOCTYPE html> <html> <head> <title>IOS 通过浏览器打开App(看美)</title> <meta charset="utf-8"> <style type="text/css"> .back{ position:absolute; top:50px;left:360px;float:left; } </style> </head> <body> <div class="back"> <p> <font size="20px"> 白日依山尽<br> 黄河入海流<br> <a href="KanMeiApp://kanmei.zsj.com" >打开看美APP</a><br> 生活多回味<br> </font> </p> </div> </body> </html> 效果: 第三:找到您写的HTML文件。(我的如下) 找到后,打开你的手机。这里我们使用模拟器替代。 打开,模拟器里面的浏览器(safari),并把您写的HTML 直接拖入进去。结果如下图: 第四:提示 1、如果你的模拟器里面没有安装(看美)App。这浏览器将打开失败。并提示如下: 2、我们就去安装我们的app(看美) 。 并双击,Home键,确保,我们要启动的App。处于关闭状态。 第六:您现在就可以,回到网页,点击蓝色字体(打开看美App),会有下面提示。 我们点击Open,就可以启动我们的App了。 看图片的头部还有 back to safari 的字体。可能有的小伙班会说,这是一个网页什么的。那我么在双击home键。查看,后台开启的项目。

redis学习之java类对redis库操作的简单封装

继上一篇安装好redis后,本篇将封装java类以方便对redis进行各种操作,因为我也是新手正在学习,只是很简单的封装。先贡献一张DB图,好让大家对各种DB整体有个了解。 通过上图知道,Redis与Memcache放在同一层级,说明他们之间有很多相似之处,另外redis在队列和栈上,数据持久化等个人觉得比MemCache优点多,两者之间的雷同网上很多学习资料,不再阐述。下面开始学习java类对Redis操作的简单封装: 一、准备工作 a.开启Redis服务(我的是在Ubuntu下) 执行命令redis-server成功开启服务(PS:执行redis-server &命令可以后台运行服务,很多时候这点很必要) b.测试连接 在Ubuntu上执行命令ifconfig查看服务IP,我的是192.168.161.130,如图: 测试连接:在ubuntu上可以ping通服务iP,现在我在Windows下看是否可ping通(redis服务的防火墙关掉),如图: 确认可以ping通就可以开始下一步了 二、java封装工作 a、 先来看下java类整体目录结构 b、贴出代码: 接口类IRedis.java: package redis; import java.util.List; import java.util.Map; import java.util.Set; public interface IRedis { //String void set(String key,String value) throws Exception;//添加 String get(String key) throws Exception;//获取 //set void sadd(String key,Set<String> value) throws Exception;//添加 void srem(String key,Set<String> value) throws Exception;//删除 Long scard(String key) throws Exception;//获取key对应的value总数 Set<String> smembers(String key) throws Exception;//获取key对应的所有value boolean sismember(String key,String value) throws Exception;//判断是否存在 String srandmember(String key) throws Exception;//随机获取数据 //map void hmset(String key,Map<String,String> map) throws Exception;//添加 Long hlen(String key) throws Exception;//mapkey个数 Set<String> hkeys(String key) throws Exception;//map中所有键值 List<String> hvals(String key) throws Exception;//map中所有value List<String> hmget(String key,String s1,String s2) throws Exception;//取出map中的name、password字段值 void hdel(String key,String s) throws Exception;//删除map中的某一个键值 password //list void lpush(String key,List<String> list) throws Exception;//添加 List<String> lrange(String key,Long start,Long end) throws Exception;//获取 void del(String key) throws Exception;//删除 //append void append(String key,String value) throws Exception;//追加 } 实现类:Redis.

阀值与阈值的差别

阀值与阈值的差别,平时总是搞错,特此明示,以正视听。 一、阀 阀 閥 fá <名> (形声。从门,伐声。本义:阀阅。即仕官人家自序功状而树立在门外左边的柱子) 同本义 [merit post]釩 在左曰阀,在右曰阅。——《玉篇》 功劳 [merit]。也作“伐” 献诚子煦,积阀亦至夏州节度使。——《旧唐书·张献诚传》 名门巨室,仕宦人家 [first family] 东都仁和里裴尚书宽子孙众盛,实为名阀。——欧阳修《新唐书·柳玭传》 又如:阀阅(有权势的仕宦人家) 依靠权势在某一方面有特殊支配地位的人物或集团 [magnate;powerfull person or family]。如:财阀;党阀;学阀;军阀 阀门 [valve]。如:安全阀;止回阀 二、阈:门槛、门限,泛指界限或范围。如:视阈;听阈。 阈值:yùzhí 〖thresholdvalue〗 在自动控制系统中能产生一个校正动作的最小输入值;刺激引起应激组织反应的最低值。 可见,其实阀值就是阈值的错写而已,并不存在阀值这个词,只是很多人不认识这个阈值的阈字,结果就让“阀值”大行其道了。 不知道这样解释是否妥当。

Ajax

Ajax(Asynchronous JavaScript and XML)技术的核心是XMLHttpRequest对象(简称XHR),XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。也就是说XHR对象取得新数据,然后通过DOM将新数据插入到页面中。Ajax通信与数据格式无关;这种技术就是无须刷新页面即可从服务器取得数据,但不一定是XML数据。 一、XMLHttpRequst对象 IE5中,XHR对象是通过MSXML库中的ActiveX对象实现的。因此,在IE中可能会遇到三种不同版本的XHR对象。其他浏览器都支持原生的XHR对象,在这些浏览器中创建XHR对象直接使用new XMLHTTPRequest() 跨浏览器方案 function createXHR(){ if(typeof XMLHTTPRequest!='undefined'){ return new XMLHTTPRequest(); }else if(typeof ActiveXObject!='undefined'){ if(typeof arguments.callee.activeXString!='string'){ var versions=['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP'],i,len; for(i=0,len=versions.length;i<len;i++){ try{ new ActiveXObject(versions[i]); arguments.callee.ActiveXString=versions[i]; break; } catch(ex){} } } return new ActiveXObject(arguments.callee.ActiveXString); }else{ throw new Error('No XHR object available'); } } var xhr=createXHR(); 1.1 XHR的用法 1)open(要发送的请求类型,请求的URL,是否异步发送请求) xhr.open('get','example.php',false); 调用open不会真正发送请求,而只是启动一个请求以备发送。 false:同步,JS代码会等到服务器响应之后再继续执行 true:异步 2)send(请求主体发送的数据||null) 要发送特定的请求,必须调用send()方法 send接受一个参数,如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必须的。调用send()之后,请求就会被分派到服务器。 3)XHR属性 在收到响应后,响应的数据会自动填充XHR对象的属性,相关的属性简介如下: responseText:作为响应主体返回的文本 responseXML:如果响应内容是“text/xml”或“application/xml”,这个属性中将保存包含着响应数据的XML DOM文档。 无论内容类型是什么,响应主体都保存在responseText属性中,而对于非XML数据,responseXML属性的值将为null。 status:响应的HTTP状态。建议通过检测status来决定下一步操作 statusText:HTTP状态的说明。跨浏览器使用时不太可靠 在接收到响应后,第一步是检查status属性,以确定响应已经成功返回。可以将HTTP状态代码200作为成功的标志。此时responseText属性的内容已经就绪,而且在内容类型正确的情况下,responseXML也应该能够访问了。此时状态代码304表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;也意味着响应是有效的。 为确保接收到适当的响应,应该像下面这样检查上述这两种状态代码: xhr.open('get','example.txt',false); xhr.send(null); if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.

ajaxSubmit异步提交

完成数据检查,form数据拼装,ajax异步提交数据,提交不刷新页面。 jQuery(document).ready(function() { /* Fullscreen background */ $.backstretch("images/login_backgroud.jpg"); /* Form validation */ $('.login-form input[type="text"], .login-form input[type="password"], .login-form textarea').on('focus', function() { $(this).removeClass('input-error'); }); $('.login-form').on('submit', function(e) { $(this).find('input[type="text"], input[type="password"], textarea').each(function(){ if( $(this).val() == "" ) { e.preventDefault(); $(this).addClass('input-error'); } else { $(this).removeClass('input-error'); } }); toSubmit(this); return false; }); function toSubmit(frm){ var obj = getFormJson(frm); $(this).ajaxSubmit({ data:obj, type:"post", //提交方式 dataType:"json", //数据类型 url:"billingLogin", //请求url clearForm:true, resetForm: true, success:function(data){ //提交成功的回调函数 if(data.status == 1){ location.href = "

redis学习之redis的安装,类库及demo

一、redis的安装 a.系统环境和说明 Linux操作系统选用Ubuntu, Redis的版本选取目前的最新稳定版本2.8.9。客户端选用了Redis的Java版本jedis b.安装步骤 wgethttp://download.redis.io/releases/redis-2.8.9.tar.gz c. 在目录下,解压按照包,生成新的目录redis-2.8.9 tar xvfz redis-2.8.9.tar.gz d. 进入解压之后的目录,进行编译 cd redis-2.8.9 sudo make 说明:如果没有明显的错误,则表示编译成功 编译前请确认是否安装了gcc,若报command not found,解决:sudo apt_get install make gcc e. 安装 sudo make install 说明:一般情况下,在Ubuntu系统中,都是需要使用sudo提升权限的 f. 在安装成功之后,可以运行测试,确认Redis的功能是否正常 sudo make test g. 启动Redis服务 查找Redis安装的目录: find / -name 'redis*' ------ 在根目录下查找名称中含有redis的文件 经过查找,发现Redis被安装到了/usr/local/bin/目录下。 接下来,启动Redis服务: /usr/local/bin/redis-server h. 查看Redis进程 ps -ef | grep redis 二、redis的类库 1. keys redis本质上一个key-value db,所以我们首先来看看他的key.首先key也是字符串类型,但是key中不能包括边界字符 由于key不是binary safe的字符串,所以像"my key"和"mykey\n"这样包含空格和换行的key是不允许的 顺便说一下在redis内部并不限制使用binary字符,这是redis协议限制的。"\r\n"在协议格式中会作为特殊字符。 redis 1.2以后的协议中部分命令已经开始使用新的协议格式了(比如MSET)。总之目前还是把包含边界字符当成非法的key吧, 免得被bug纠缠。 另外关于key的一个格式约定介绍下,object-type:id:field。比如user:1000:password,blog:xxidxx:title 还有key的长度最好不要太长。道理很明显占内存啊,而且查找时候相对短key也更慢。不过也推荐过短的key,

R语言-正则表达式

R语言中正则表达式 内容概览 有时候我们要处理的是非结构化的数据,例如网页或是电邮资料,那么就需要用R来抓取所需的字符串,整理为进一步处理的数据形式。R语言中有一整套可以用来处理字符的函数,在之前的 博文 中已经有所涉及。但真正的要用好字符处理函数,则不得不用到正则表达式。 正则表达式(Regular Expression、regexp) 是指一种用来描述一定数量文本的模式。熟练掌握正则表达式能使你随心所欲的操作文本来达成目标。其实学习正则表达式并没有想像中的那么困难。最好方法是从例子开始,然后多练习,多使用。网络上已经有许多不错的参考资料,例如 这篇 或 那篇 。本文假设你对正则表达式有了基本的了解,下面我们来看看如何在R里面来使用它。 R语言处理文本的能力虽然不强,但适当用用还是可以大幅提高工作效率的,而且有些文本操作还不得不用。高效处理文本少不了正则表达式(regular expression),虽然R在这方面先天不高效,但它处理字符串的绝大多数函数都使用正则表达式。 正则表达式简介: 正则表达式不是R的专属内容,这里也只简单介绍,更详细的内容请查阅其他文章。正则表达式是用于描述/匹配一个文本集合的表达式。 1. 所有英文字母、数字和很多可显示的字符本身就是正则表达式,用于匹配它们自己。比如 'a' 就是匹配字母 'a' 的正则表达式 2. 一些特殊的字符在正则表达式中不在用来描述它自身,它们在正则表达式中已经被“转义”,这些字符称为“元字符”。perl类型的正则表达式中被转义的字符有:. \ | ( ) [ ] { } ^ $ * + ?。被转义的字符已经有特殊的意义,如点号 . 表示任意字符;方括号表示选择方括号中的任意一个(如[a-z] 表示任意一个小写字符);^ 放在表达式开始出表示匹配文本开始位置,放在方括号内开始处表示非方括号内的任一字符;大括号表示前面的字符或表达式的重复次数;| 表示可选项,即 | 前后的表达式任选一个。 3. 如果要在正则表达式中表示元字符本身,比如我就要在文本中查找问号‘?’, 那么就要使用引用符号(或称换码符号),一般是反斜杠 '\'。需要注意的是,在R语言中得用两个反斜杠即 ‘\\’,如要匹配括号就要写成 ’\\(\\)‘ 4. 不同语言或应用程序(事实上很多规则都通用)定义了一些特殊的元字符用于表示某类字符,如 \d 表示数字0-9, \D 表示非数字,\s 表示空白字符(包括空格、制表符、换行符等),\S 表示非空白字符,\w 表示字(字母和数字),\W 表示非字,\< 和 \> 分别表示以空白字符开始和结束的文本。 5. 正则表达式符号运算顺序:圆括号括起来的表达式最优先,然后是表示重复次数的操作(即:* + {} ),接下来是连接运算(其实就是几个字符放在一起,如abc),最后是表示可选项的运算(|)。所以 'foot|bar' 可以匹配’foot‘或者’bar‘,但是 'foot|ba{2}r'匹配的是’foot‘或者’baar‘。关于正则表达式

可视化篇:Echarts个人轨迹可视化实现

写在最前 下面是《可视化篇:效果图》中第8、9张的实现说明 其中: 1. 个人轨迹的可视化是echart通过调用百度地图API后实现,关于Echarts如何调用百度地图API,请参考上一篇文章《Echarts引入百度地图》 2. 下图展示的个人轨迹均为虚拟数据 3. 本文只做单用户轨迹展示说明,并未深入探讨批量用户轨迹的可视化及优化 4.使用工具为:Echarts 1.Echart版本说明及模块化文件引入 目前百度搜索能看到的有echart2和echart3,由于echart3已不提供百度地图实例化的样本(若强行用echart3,需自行写好相关js脚本),所以下文是基于echart2,下载地址为:http://echarts.baidu.com/build/echarts-2.2.7.zip模块化文件的引入主要有main.js,map.js,还有echart.js require.config({ paths: { echarts: "echarts", }, }); require( [ "echarts", "echarts/chart/main", "echarts/chart/map", ], 其中: main.js文件对应在下载的echart2压缩包目录echarts-2.2.7\extension\BMap\src下,该文件是杨骥(echart团队)写的百度地图在echart上的扩展文件 map.js文件对应目录为:build\dist\chart,再声明一次,引入百度地图时,dist目录需全部复制到开发文件相应目录下 echarts.js同样存在于dist文件 此处详细参见《Echarts引入百度地图》一文。 2.个人轨迹展示的思考及实现 2.1 对于个人轨迹的可视化,最初的设想是: 在百度地图上,搭配时间轴timeline,随着时间的变化用户轨迹的演变,后来在用echart写时发现timeline属性始终对应不到options列表,无法渲染options下用户的轨迹参数列表,再后来与R REmap包作者交谈中进一步确认,echart中timeline目前还无办法在百度地图上渲染,这里应该知会一下echart团队的,下面就不对timeline使用做过多说明了。 除上述不同时间不同地点外,为更好展示轨迹线下的意义,还需要做进一步工作,即不同时间不同地点不同事件,如此对于个人轨迹才有比较契合展示。 最终效果如下: 上班场景: 同行逛街: 2.2 个人轨迹的echart实现 2.2.1 为实例化百度地图背景构建一个容器 <head> <meta charset="utf-8"> <style type="text/css"> body { margin: 0; } #main { height: 100%; } </style> </head> <body> <div id="main"></div> Margin设为0则与浏览器无边界融合,div属性容器id,后面js脚本里需要用到该属性,并将echart填充到该容器里,当然,div可以有多个,故可以填充多个echart实例。 实例化后再js脚本里调用echart api即可: var BMapExt = new BMapExtension($('#main')[0], BMap, echarts,{ enableMapClick: false }); var map = BMapExt.

Caffe中卷基层和全连接层训练参数个数如何确定

慢慢填坑中,今天来仔细讲一下卷基层和全连接层训练参数个数如何确定的问题。我们以Mnist为例,首先贴出网络配置文件: name: "LeNet" layer { name: "mnist" type: "Data" top: "data" top: "label" data_param { source: "examples/mnist/mnist-train-leveldb" backend: LEVELDB batch_size: 64 } transform_param { scale: 0.00390625 } include: { phase: TRAIN } } layer { name: "mnist" type: "Data" top: "data" top: "label" data_param { source: "examples/mnist/mnist-test-leveldb" backend: LEVELDB batch_size: 100 } transform_param { scale: 0.00390625 } include: { phase: TEST } } layer { name: "conv1" type: "Convolution" bottom: "

Android 自定义带进度显示的半圆形进度条ArcTextProgressBar

自定义ArcTextProgressBar 这个控件最终需要实现如下效果: 1、进度条采用半圆弧形式呈现; 2、圆弧上有已完成的进度提示; 见下面效果图: 其他一些诸于设置进度条宽度、颜色,进度文字圆大小等属性具体见代码中的定义,好废话不说,上代码: 首先是自定义的属性,这样便于在xml文件中设置属性: <declare-styleable name="ArcTextProgressBar"> <attr name="arc_text_progress_stroke_width" format="integer" /> <attr name="arc_text_progress_text_bg_circle_diameter" format="integer" /> <attr name="arc_text_progress_text_string_prefix" format="string" /> <attr name="arc_text_progress_text_string_suffix" format="string" /> <attr name="arc_text_progress_min_progress" format="integer" /> <attr name="arc_text_progress_current_progress" format="integer" /> <attr name="arc_text_progress_max_progress" format="integer" /> <attr name="arc_text_progress_total_arc_color" format="color" /> <attr name="arc_text_progress_current_arc_color" format="color" /> <attr name="arc_text_progress_circle_text_bg_color" format="color" /> <attr name="arc_text_progress_circle_text_color" format="color" /> <attr name="arc_text_progress_circle_text_size" format="integer" /> </declare-styleable> 然后是ArcTextProgressBar.java文件,具体说明见注释,应该比较清楚: public class ArcTextProgressBar extends View { private int diameter = 600; // 圆弧直径 private int mStokeWidth = 40; // 进度条宽度 private int mTextBgCircleDiameter = 20; // 进度条圆形背景上的致敬 private String mTextStringPrefix = "

为什么计算机最小的存储单位是字节?而最小到的传输单位是bit?

数据存储是以“字节”(Byte)为单位,数据传输是以大多是以“位”(bit,又名“比特”)为单位,一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个字节(Byte,简写为B),是最小一级的信息单位。 还可以从以下几个方面来理解: 1.字节(Byte)是电脑中表示信息含义的最小单位,因为在通常情况下一个ACSII码就是一个字节的空间来存放。而事实上电脑中还有比字节更小的单位,因为一个字节是由八个二进制位组成的,换一句话说,每个二进制位所占的空间才是电脑中最小的单位,我们把它称为位,也称比特(bit)。由此可见,一个字节等于八个位。人们之所以把字节称为电脑中表示信息含义的最小单位,表示最基本的字符,是因为一个位并不能表示我们现实生活中的一个相对完整的信息。另外,内存中运算的最小存储单位是字节,位运算也是在一个字节的存储单位的基础上进行的,所以存储的最小单位可以理解为字节。 2.bit是二进制数的一位包含的信息或2个选项中特别指定1个的需要信息量称为一比特,是表示信息的最小单位,只有两种状态:0和1。电脑内部的电路工作有高电平和低电平两种状态.所以就用二进制来表示信号,以便计算机识别。所以计算机能传输的最小单位当然是你信号的单位bit,而不是字节,串口最小也有一位传递的。另外数字信息流的基本单位是bit(比特),时间的基本单位是s(秒),因此bit/s(比特/秒)是描述带宽的单位,1bit/s是带宽的基本单位,所谓的带宽其实指的是传输速度的快慢,也就是指在一个固定的时间内(1秒),能通过的最大位数据。

什么样的数据应该放入缓存

把数据放入缓存,有三个标准: 1.数据量不大 2.访问频率高 3.数据更改频率低 转载于:https://www.cnblogs.com/hwgok/p/5494915.html

第2章:Android的编译环境--build系统

2.0 build简介 Android的build系统基于GNU Make 和shell 构建的一套编译环境。这套系统定义了大量的变量和函数,无论编写一个产品的配置文件还是一个模块的Android.mk文件,都不用直接和GNU Make打交道,只需要理解Android提供的编译变量和函数,就能够方便的将我们开发的模块加入到Android的build体系中。Android系统build分类: 1、build/core 目录下的文件,这是Android Build的系统框架核心; 2、device目录下的文件,存放的是具体的产品配置文件; 3、各个模块的编译文件:Android.mk,位于模块的原文件目录下。 2.1 Android Build系统核心 Android Build系统核心在目录buil/core,这个目录中有mk文件、shell脚本和per脚本,他们构成Android Build系统的基础和架构。 编译Android系统常用命令: $source build/envsetup.sh $lunch $make 2.1.1 编译环境的建立 1. envsetup.sh 文件的作用 执行Android系统的编译,必须先执行envsetup.sh脚本,这个脚本会建立Android的编译环境。其具体执行的是建立shell命令以及调用add_lunch_combo命令,这个命令的将调用该命令的所传递的参数存放到一个全局的数组变量LUNCH_MENU_CHOICES中。执行lunch时打印的正是这个数组的内容。 envsetup.sh脚本中定义的常用shell命令: 命令说明lunch指定当前编译的产品croot快速切换到源码的根目录,方便开始编译m编译整个源码,但不用讲当前的目录切换到源码的根目录mm编译当前目录下的所有模块,但是不编译他们的依赖项cgrep对系统中所有的C/C++文件执行grep命令sgrep对系统中所有的源文件执行grep命令 2 lunch命令的功能 lunch命令如果没有参数,系统会打印出产品的列表供选择lunch的参数格式如下: “product_name”必须是系统中已经定义的产品名称“build_variant”必须是“eng”、“user”和“userdebug”三者之一 “<product_name>-<build_variant>” lunch命令主要作用是根据用户输入或选择的产品来设置与具体产品相关的环境变量 这些相关的环境变量有: TARGET_PRODUCT:对应“product_name”TARGET_BUILD_VARIANT:对应“build_variant”TARGET_BUILD_TYPE:一般是“release” 2.1.2 build相关的环境变量 执行完lunch之后,系统会打印出当前配置所生成的环境变量,这些环境变量将影响编译过程 环境变量的意义: PLATFORM_VERSION_CODENAME:平台版本名称,通常是AOSPPLATFORM_VERSION:Android平台的版本号TARGET_PRODUCT:所编译产品的名称TARGET_BUILD_VARIANT:表示编译产品的类型,可能的值有eng、user和userdebugTARGET_BULD_TYPE:表示编译的类型,可选的值是release和debugTARGET_BUILD_APPS:编译Android系统时,这个变量为NULL。使用build系统编译单个模块时为所编译模块的路径TARGET_ARCH:编译目标的CPU架构TARGET_ARCH_VARIANT: 编译目标的CPU架构版本TARGET_CPU_VARIANT:编译目标的CPU代号TARGET_2ND_ARCH:编译目标的第二CPU架构HOST_ARCH:编译平台架构HOST_OS:编译平台使用的操作系统HOST_OS_EXTRA:编译平台操作系统的一些额外信息,可包括内核版本号、产品名称、公司特有的标志等BUILD_ID:BUILD_ID的值会出现在编译的版本信息中,可以利用这个环境变量来定义公司的特有标志OUT_DIR:指定编译结果的输出目录对环境变量的修改可以放到产品的定义文件中,后面讲解 若只是临时改变这些变量的值,可以通过make命令中加入参数的方式完成,如下例子 make BUILD_ID="Android L" 2.1.3 Build系统的层次关系 设置好环境变量后,make命令就会开始执行编译过程了 编译产品的目的是生成用于“刷机”的各种image文件 这些image文件时由一个个小小的文件组成的 有些是从源码中编译产生的,有些是简单的复制就可以了,此外编译过程中也会产生一些配置文件build系统的主要工作: 生成image文件收集并编译模块、复制二进制文件、产生配置文件管理并执行这些产品配置文件执行make命令会调用build目录下的Makefile文件,其内容如下: main.mk文件是Android Build系统的主控文件,从main.mk开始,将通过include命令将其余所有需要的.mk文件包含进来,最终在内存中形成一个包括所有编译脚本的集合 include build/core/main.mk Android Build系统的编译文件的包含关系: Android Build系统会在以下三个文件中引入具体产品的配置文件和各个模块编译文件 AndroidProduct.mk、BoardConfig.mk和Android.mkconfig.mk文件中,会有4出引入combo目录下的select.mk文件,目前通常第二个编译平台未定义,一般只包含3次select.mkclang 目录下的config.mk和seleck.mk文件一样按照同样的规则包含进3个不同的mk文件combo目录下额这些mk文件定义了GCC编译器的版本和参数clang目录下的mk文件则定义了LLVM编译器clang的路径和参数 图 4. 主要的 Make 文件及其包含关系Build系统的主要编译脚本简介

光衰、功率匹配

发射光功率和接收灵敏度 接收灵敏度 是指光模块在一定的光功率范围才能发现光信息,太小 或者 太大 皆无法收到光。 单模 1310nm 0.34dB/km 单模 1550nm 0.20dB/km 多模 1300nm <0.8dB/km 多模 850nm <3.0dB/km 长途干线用 ED FA放大,或者多几个中继 单模一般在0- -24之间,双模在0- -20dBm之间小于最大限值就正常。每公里的衰减和波长有关系。 光功率太强也容易损坏收发器,如有必要可以加个衰减器。短距离尾纤的话还是推荐添加。 如果光衰过大,首先不能太过于弯曲,优先检查光接口是否污染,其次分析设备接收问题,最后线路。 单模光纤,如使用1330波长的,每公里为0.4DB,如使用1550波长的为每公里0.25DB。一般双纤收发器的使用1330波长,如单纤的两个波长都用。 http://support.huawei.com/ecommunity/bbs/10233041.html 光功率过高、过低都不能正常工作;具体范围和光模块强相关 一般情况下,ONU GPON口接收光功率的正常范围是-27dBm~-8dBm。 工程上一般对光功率要求: 灵敏度+3----过载点-5 OLT下联ONU如果不分光,会出现这种情况,pppoe拨号正常拨上去,但网页打不开。这个现象自己亲身碰到过,很有意思。 记住两个概念,发射光功率和接收灵敏度 接收灵敏度是指光模块在一定的光功率范围才能发现光信息,太小或者太大皆无法收到光。 发射功功率则是光模块发射的光信号功率。 你这个连接了光衰之后才能收到光,显然是因为光功率太大,经过衰减后才打到ONU光模块的接收灵敏度阈值内。 再回答你正常的光衰范围这个问题:【直接OLT接ONU ONU接受不到光,接了个光衰后才收到光。】 你所谓的正常的光衰其实就是在问“接收灵敏度”,这个值是和光模块强相关的,不同的光模块不同。目前你提供的信息无法提供答案。 不分光直连会因为线路的光衰减太小,导致到达ONU光模块的光功率太强,超过了ONU光模块的光接收灵敏度,ONU与OLT之间通信不正常

PHP实现页面静态化

为什么要页面静态化? 1.动态文件执行过程:语法分析-编译-运行 2.静态文件,不需要编译,减少了服务器脚本运行的时间,降低了服务器的响应时间,直接运行,响应速度快;如果页面中一些内容不经常改动,动态页面静态化是非常有效的加速方法。(纯静态,伪静态还是需要PHP解释器的) 3、生成静态URL利于SEO,利于蜘蛛抓取和收录,有利于提升排名 优化页面响应时间方法 1.动态页面静态化 2.优化数据库 3.负载均衡 4.使用缓存等等 //动态页面静态化一般用于不经常改动的地方,频繁改动的地方一般不适用静态化,可用伪静态(例如微博等) 静态化详细介绍 1、纯静态分为局部静态化(局部动态化,使用AJAX动态获取数据)和纯静态化。 伪静态:改变URL(需要服务器支持,如:apache等等) 2、从URL结构以及页面名称看,伪静态和静态页面是一样的。伪静态的页面后缀可以是html htm 或者是目录格式 伪静态只是改变了URL的表现形式,实际上还是动态页面 静态页面可以节省服务器资源,而伪静态严格说是增加服务器资源消耗的 总结,在SEO方面,伪静态和静态页面的功能是相同的,但是伪静态本质上还是动态页面,所以消耗资源是和动态页面一样的,而且因为Rewrite服务器还需要消耗额外的资源。 Buffer缓冲区认知 1、开启buffer 在php.ini中的output_buffering开启在php文件中使用ob_start()函数开启 ; Default Value: Off ; Development Value: 4096 ; Production Value: 4096 ; http://php.net/output-buffering output_buffering = 4096 2、获取缓冲区的内容 output_buffering=on 需要先开起,才能调用ob_get_contents()函数。但是,如果不开启output_buffering时,当在头文件中调用函数ob_start()函数时,ob_get_contents()也能使用。 ob_get_content();//返回输出缓冲区的内容; PHP如何实现页面纯静态化 基本方式 1、file_put_contents 2、使用PHP内置缓存机制实现页面静态化output_buffering ob_start()//如果php.ini已经开启,那么这里会开启一个新的输出缓冲区; ob_get_contents()//获取输出缓冲区内容; ob_clean()//清空输出缓冲区内容,但是不会删除输出缓冲区 ob_get_clean//获取输出缓冲区内容并且删除输出缓冲区,等价于ob_get_contents和ob_end_clean) 下方这段代码,运行是不会有输出的 原因就是输出缓冲区被清空了,看上图理解 ob_start(); echo 777; echo 000; ob_clean(); echo ob_get_contents(); 纯静态实现,代码和实现逻辑参考: <?php /** * 触发系统生成纯静态化页面业务逻辑 * 有3种方案: * 第一:定时扫描程序(利用crontab来处理) * 第二:手动触发方式,人为触发 * 第三:页面添加缓存时间,在页面中控制时间来操作 */ //=========================================== //生成纯静态文件步骤 //1、连接数据库,然后从数据库里面获取数据 //2、把获取到的数据填充到模版文件里面 //3、需要把动态的页面转为静态页面,生成静态化文件 //============================================ //PHP实现页面静态化有以下步骤: //1:A.

Git 实用命令总结

初始化一个目录 git init 添加本地修改的文件 git add . 其中.表示添加当前目录下面所有修改&新增的文件,如果想单独add指定目录或文件将.替换成目录或文件地址就可以了 提交更新 git commit -m '注释' 这里的提交是提交到了本地仓库. 删除文件 git rm file/dir 直接使用shell进行rm file操作后版本还需要使用git rm file命令从版本库从删除文件,其中如果是删除目录,需要增加一个-r参数 查看提交历史 git log git log命令能查看所有版本的提交历史以及每次提交的版本号和注释,并且每次提交都会有一个唯一的版本号。 使用git log --graph能够以’图’的方式更形象的展示提交记录,如果像显示的简洁一点,可以再加一个 –oneline 参数,就能把每一个提交合并到一行显示 HEAD HEAD是git中一个特殊的指针,指向当前的分支的最新的一个commit,这个概念很重要。 HEAD^表示当前分支的上一个commit版本, HEAD^^表示上上个版本,也可以用HEAD~n进行表示,n代表之前第几个版本 如果本地修改了一些东西,不想要了,可以用命令git reset --hard HEAD恢复到上次提交后的版本。如果想恢复上上个版本,可以用命令git reset --hard HEAD^^如果想根据版本号恢复到指定版本可以用命令git reset --hard COMMIT_VERSION.,COMMIT_VERSION表示版本号 使用git rest命令回退版本后再使用git log命令查看提交记录时发现当前版本之后的记录都没有了。如果此时又想恢复到当前版本之后的一个版本,可以用git reflog查看git的每次操作记录,从里面找到版本好,然后重新使用git reset命令就可以进行恢复了 暂存区 也可以称为’工作目录/working directory’上一次提交后的所有更改都被保存在’暂存区’,可以通过git status命令查看当前暂存区中所有的更改,当使用git add/rm 等命令操作时,实际上是对暂存区的操作,当使用git commit命令时,会将暂存区的内容一次性提交到当前分支。 比对文件 git diff git diff file 可以通过git diff查看一个文件与当前HEAD版本中这个文件内容的区别。 也可以通过git diff COMMIT_VERSION 比对某个版本与当前暂存区文件内容的区别,如果不指定COMMIT_VERSION,默认为HEAD 也可以通过git diff COMMIT_VERSION file比对指定文件某个版本与当前展存区的区别

面试时如何谈自己做过的项目

前段时间换工作,搬家什么的,学习感觉耽误了,但在找工作面试的时候,感觉下面一些意见很有用,分享一下 1、介绍项目架构 把项目整体架构描述一遍,系统环境和软件架构可以一句话带过。网络架构可以按照网络拓扑来说明,顺便把服务器角色和业务流程说一下。要突出运维体系架构中的关键点:监控报警、负载均衡、冗余、高可用、数据库集群、存储、安全、虚拟化等的部署和设计。 2.自己负责的技术部分 前面的介绍可以不涉及到细节,但在介绍自己主要做的部分时,要做好面试官询问细节的思想准备,毕竟这一块才能突显出你的能力和水平。 3、你认为的闪光点 把项目中自己认为好的地方提出来,可以是架构设计上的也可以是具体优化细节上的,甚至可以是编码实现上的。 4、你认为需要改进的地方 很多人介绍项目时可能会忽略了这一点,就是说如果时间、资源允许,现有的项目还有什么地方需要改进。 5、项目的管理 如果是项目负责人,可以谈一谈项目进度如何安排的,遇到时间上、人员上的问题如何解决,这一部分不仅可以考察人的管理能力,也可以考察人的团队合作能力。 6、突出你的责任心 对工作的认真负责,是每一个面试官都希望看到的。在工作当中,即便你的技术不是很全面或很好,但是你对工作很认真负责,愿意学习和承担压力,这样就有培养的价值也符合企业用人的理念,企业也会认真考虑你的。 ↑参考资料:http://www.studyofnet.com/news/957.html 例如项目可以这样大概描述一下:整个项目是基于B/S模式,应用Struts Spring Hibernate DWR和ExtJS五个框架实现了一个绚丽的客户关系管理系统。分为View层(显示层)、Control层(控制层)、Service层(业务逻辑层)、DAO层(数据库访问对象层)。利用Spring的依赖注入和面向切面特性,hibernate的数据持久化技术、Struts的控制器、ExtJS用于View层实现了用户权限管理、日程安排、客户关系管理、销售管理、档案管理、统计数据、商务联系管理等模块。 现在新的公司用到了很多前公司没用到的,譬如redis,mybatis,jboss,高并发等等,虽然要用到的技术很多,但正是学习的时候,以后会陆续更新这些技术的文章,加油!

JavaSE入门学习37:Java集合框架之Map接口及其实现类HashMap和TreeMap

一Map接口 Map接口中的每个成员方法由一个关键字(key)和一个值(value)构成。Map接口不直接继承于Collection接口,因 为它包装的是一组成对的"键-值"对象的集合,而且在Map接口的集合中也不能有重复的key出现,因为每个键只能与 一个成员元素相对应。 Map接口定义了存储"键(key)——值(value)映射对"的方法。实现Map接口的类用来存储键值对。Map接口中包含 了一个keySet()方法,用于返回Map中所有key组成的Set集合。 Map接口的特点有: 1)Map接口提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储 的,能够实现根据key快速查找value。 2)Map中的键值对以Entry类型的对象实例形式存在。键(key值)不可重复,value值可以。 3)每个键最多只能映射到一个值。 4)Map接口提供了分别返回key值集合,value值集合以及Entry(键值对)集合的方法。 5)Map同样也支持泛型,形式如:Map<K,V>。 6)Map接口中存储的键—值对通过键来标识,所以键值不能重复,即同一个Map对象的任何两个key通过equals() 方法比较总是返回false。 Map接口中定义的方法有: Map接口的主要有三个实现类,分别是:HashMap、TreeMap和HashTable。一般情况下,我们用的最多的是 HashMap,在Map中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历 键,那么TreeMap会更好。如果需要输出的顺序和输入的相同。那么用HashMap的子类LinkedHashMap可以实现, 它还可以按读取顺序来排列。 二HashMap实现类 Hashmap类是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访 问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要 同步,可以用Collections集合类的synchronizedMap()方法使HashMap类具有同步的能力。 由于HashMap里的不能重复,所以HashMap里最多只有一对key-value值为null,但可以有无数多项key-value对 的value为null。 HashMap重写了toString()方法方法总是返回如下格式的字符串:{key1 = value1,key2 = value2...} HashMap判断两个key相等的标准是:两个key通过equasl()方法比较返回ture,两个key的hashCode值相等。 HashMap的特点: 1)HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现。 2)HashMap中的Entry对象是无序排列的。 3)Key值和value值都可以是null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)。 HashMap实现类的方法: 实例: import java.util.*; public class TestHashMap { public static void main(String[] args) { Map<Dog, Integer> hashMap = new HashMap<Dog, Integer>(); Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("

C#添加第三方控件

在“工具箱”窗口中鼠標右鍵,“選擇項”,“選擇工具箱項”中進行選擇,可以選擇COM組件

使用Arduino与L298N(红板) 驱动直流电机

L298N 简介 L298N驱动模块,可以驱动2个直流电机,可分别实现正转,反转功能. Bom表 Arduino Uno * 1 L298N驱动模块 * 1 直流电机 * 2 9v 电池 * 1 跳线 若干 Arduino uno + L298N 驱动模块接线 注意:如果电压不够,电机有可能不会转哦,所以要外置7V-12V电源. 程序源码 程序打包下载地址:https://u16460183.ctfile.com/fs/16460183-295173804 把程序上传到主板上,接上外部电源,电机就转起来了. 这里选用IO口为5,6,9,10,这四个均支持PWM,可以通过占空比代码实现控制转动速度的快慢. -------------------↓ 可以按下这个按钮复制代码 -------------------↓ //LingShun Lab int input1 = 5; // 定义uno的pin 5 向 input1 输出 int input2 = 6; // 定义uno的pin 6 向 input2 输出 int input3 = 9; // 定义uno的pin 9 向 input3 输出 int input4 = 10; // 定义uno的pin 10 向 input4 输出 void setup() { // Serial.

对象转型(向上转型和向下转型)

一、对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型。转型的意思是:如把float类型转成int类型,把double类型转成float类型,把long类型转成int类型,这些都叫转型。把一种形式转成另外一种形式就叫转型。除了基础数据类型的转型之外(基础数据类型的转型:大的可以转成小的,小的也可以转成大的。),对象领域里面也有对象之间的转型。 1.1.对象转型实例一 public class TestClassCast { public static void main(String[] args) { Animal a = new Animal("name"); Cat c = new Cat("catname","blue"); /** * a instanceof Animal这句话的意思是a是一只动物吗? * a是Animal这个类里面的是一个实例对象,所以a当然是一只动物,其结果为true。 */ System.out.println(String.format("a instanceof Animal的结果是%s",a instanceof Animal));//true /** * 这里判断说“动物是一只猫”,不符合逻辑,所以打印出来的结果是false。 */ System.out.println(String.format("a instanceof Cat的结果是%s",a instanceof Cat)); /** * 这句话比较有意思了,a本身是Animal类的实例对象的引用, * 但现在这个引用不指向Animal类的实例对象了,而是指向了Dog这个类的一个实例对象了, * 这里也就是父类对象的引用指向了子类的一个实例对象。 */ a = new Dog("bigyellow", "yellow"); System.out.println(a.name);//bigyellow /** * 这里的furColor属性是子类在继承父类的基础上新增加的一个属性,是父类没有的。 * 因此这里使用父类的引用对象a去访问子类对象里面新增加的成员变量是不允许的, * 因为在编译器眼里,你a就是Animal类对象的一个引用对象,你只能去访问Animal类对象里面所具有的name属性, * 除了Animal类里面的属性可以访问以外,其它类里面的成员变量a都没办法访问。 * 这里furColor属性是Dog类里面的属性,因此你一个Animal类的引用是无法去访问Dog类里面的成员变量的,

Windows 性能监视器的基本指标说明(CPU,内存,硬盘参数)

作为一个系统工程师来说,要看懂监控的数据至关重要,关系着优化和分析出现的问题。我是在运维过程中要用到的。因此,今天给出Windows 性能监视器的一些基本指标(CPU,内存,硬盘参数),希望对大家将来优化和分析问题提供帮忙。 直接在window系统中点击win键输入“性能监视器”就可以看到,参数设置类似这样: CPU Windows -Processor 指标名称 指标描述 指标范围 指标单位 CPU利用率 (% Processor Time) % Processor Time指处理器执行非闲置线程时间的百分比。这个计数器设计成用来作为处理器活动的主要指示器。它通过在每个时间间隔中衡量处理器用于执行闲置处理线程的时间,并且用100%减去该值得出。可将其视为范例间隔用于做有用工作的百分比。 根据应用系统情况,在80%±5%范围内波动为宜。过低,则服务器CPU利用率不高;过高,则CPU可能成为系统的处理瓶颈。 % 中断率 (Interrupts/sec.) 每秒钟设备中断处理器的次数。在完成一个任务或需要注意时,装置会发出中断讯号给处理器。可以产生中断的装置包括系统定时器、鼠标、数据通讯联机、网络卡以及其它的外部装置。在中断过程中,一般的执行绪执行将被暂停,而且一个中断可以使处理器切换到另一个具有较高优先等级的执行绪。频率中断是频繁和周期性的,并且中断动作在背景执行。 取决于处理器,越低越好;不宜超过1,000; 如果该值显著增加而系统活动没有相应的增加,则表明存在硬件问题,需要检查引起中断的网络适配器、磁盘或其他硬件。 次/sec 系统调用率 System Call/sec. 指运行在计算机上的所有处理器调用操作系统服务例行程序的综合速率。这些例行程序执行所有在计算机上的如安排和同步活动等基本的程序,并提供对非图形设备、内存管理和名称空间管理的访问。 如果Interrupts/sec大于System Calls/sec.,则系统中某一硬件设备产生过多的中断。 次/sec Processor Queue Length 处理器队列的线程数量。此计数器只显示就绪线程,而不是正在运行的线程。 如果处理器队列中总是有两个以上的线程通常表示处理器堵塞。 进程切换率 Context Switches/sec 指计算机上的所有处理器全都从一个线程转换到另一个线程的综合速率。当正在运行的线程自动放弃处理器时出现上下文转换,由一个有更高优先就绪的线程占先或在用户模式和特权 (内核) 模式之间转换以使用执行或分系统服务 如果此计数器的数值较大,则表明锁定竞争很激烈,或者线程在用户和内核模式之间频繁切换。 PS: Processor/% Processor Time 阀值:处理器的阀值一般设为85%。 含义:这个计数器是处理器活动的主要指标。高数值并不一定是坏事,但是如果其他处理器相关的计数器(比如% Privileged Time 或者Processor Queue Length)线性增加的话,高CPU使用率就值得调查了。 Processor/% Privileged Time 阀值:如果数值持续大于75%就表示存在瓶颈。 含义:这个计数器表示一个线程在特权模式下所使用的时间比例。当你的程序调用操作系统的方法(比如文件操作,网络I/O或者分配内存),这些操作系统的方法是在特权模式下运行的。 Processor/% Interrupt Time 阀值:取决于处理器 含义:这个计数器表示处理器接收处理硬件中断所使用的时间比例。这个值间接指出产生中断的硬件设备活动,比如网络变化。这个计数器显著增加的话表示硬件可能存在问题。 System/Processor Queue Length 阀值:平均值持续大于2那么表示CPU存在瓶颈 含义:如果就绪的任务超过处理能力线程就会被放进队列。处理器队列是就绪但是未能被处理器执行的线程的集合,这是因为另外一个线程正在执行状态。持续或者反复发生2个以上的队列则明确的表示存在处理器瓶颈。你也能通过减少并发取得更大的吞吐量。 你可以结合Processor/% Processor Time来决定增加CPU的话你的程序是否能够受益。即使在多处理器的电脑上,对于CPU时间也是单队列。因此,在多处理器电脑上,Processor Queue Length (PQL)的值除以用来处理负载的CPU个数。 如果CPU非常忙(90%以上的使用率),PQL的平均值也持续大于2/CPU,这是应该存在CPU瓶颈而且能够从更多的CPU中受益。或者,你可以减少线程的数量以及增加应用程序层的队列。这会引起少量的Context Switching,但是少许的Context Switching对于减少CPU负载是有好处的。PQL大于2但是CPU使用率却不高的的常见原因是对CPU时间的请求随机到达而且线程却从处理器申请到不对称的CPU时间。这意味着处理器并不是瓶颈,而你的线程逻辑是需要改进的。

python3+scapy扫描获取局域网主机ip和mac

python3+scapy扫描获取局域网主机ip和mac ''' python3 安装scapy-python3 注:linux,可能需要以root登陆,避免出现permission error Scapy还包含内建函数arping(),该函数实现的功能和以上的两个命令类似: arping("192.168.1.*") ''' from scapy.all import srp, Ether, ARP IpScan = '192.168.114.1/24' try: ans,unans = srp(Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(pdst=IpScan), timeout=2) except Exception as e: print(e) else: for send, rcv in ans: ListMACAddr = rcv.sprintf("%Ether.src%---%ARP.psrc%") print(ListMACAddr) 参考: Scapy中文使用文档

mysql5中大数据错误:Packet for query is too large (***>***). You can change this value on the ser

mysql5数据,插入或更新字段有大数据时(大于1M),会出现如下错误: SEVERE: Servlet.service() for servlet [webs] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.TransientDataAccessResourceException: Hibernate flushing: Could not execute JDBC batch update; SQL [update t_article set (省略部分...)author_id=? where id=?]; Packet for query is too large (2048 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.; nested exception is java.sql.BatchUpdateException: Packet for query is too large (1117260 > 1048576).

ubuntu 16.04 启动进入命令行的解决方案 ubuntu 16.04 boot into text mode

ubuntu 16.04 启动进入命令行的解决方案 boot ubuntu 16.04into text mode 步骤如下: sudo vi /etc/default/grub Comment the line GRUB_CMDLINE_LINUX_DEFAULT=”quiet” , by adding # at the beginning Change GRUB_CMDLINE_LINUX=”" to GRUB_CMDLINE_LINUX=”text” Uncomment this line #GRUB_TERMINAL=console, by removing the # at the beginning sudo update-grub sudo systemctl set-default multi-user.target

POS协议解析

单纯的讲IS08583那些字段的定义,我觉得没有什么意思,标准中已经对每个字段解释 的非常详细了,如果你觉得理解英文版的ISO8583规范有些困难,网上也有同行为我们翻译好的中文版ISO8583规范,所以我的目的是达到阅读本文后 能够对ISO8583知其然,亦知其所以然,使以前基本没有接触它的人也能够达到掌握ISO8583报文规范。 好了,我们该转入正题了。 最开始时,金融系统只有IBM这些大的公司来提供设备,象各种主机与终端等。在各个计算机设备之间,需要交换数据。我们知道数据是通过网络来传送的,而在网络上传送的数据都是基于0或1这样的二进制数据,如果没有对数据进行编码,则这些数据没有人能够理解,属于没有用的数据。起初的X.25、SDLC以及现在流行的TCP/IP网络协议都提供底层的通讯编码协议,它们解决了最底层的通讯问题,能够将一串字符从一个地方传送到另一个地方。但是,仅仅传送字符串是没有太大意义的,怎样来解析字符串代表什么内容是非常重要的,否则传送一些“0123abcd”的字符串也是无用的乱码。 让我们随着时光回到几十年前的某个时刻,假设我们被推到历史的舞台上,由我们来设计一个通用报文协议,来解决金融系统之间的报文交换,暂且称该协议叫做ISO8583协议。此时,技术是在不断的前行,当初IBM一支独秀的局面好像已经不妙了,各种大小不一的公司都进入金融行业以求能有所斩获,呈一片百花齐放的局面。我们怎样来设计一个报文协议,能够将这些如雨后春笋般出现的所有公司都纳入进来,其实也不是一件很简单的事。 我们还是先一步步的来考虑吧。金融行业其实涉及到的数据内容并不是成千上万,无法统计,恰恰相反,是比较少的。我们都可以在心底数得过来,象交易类型、帐号、帐户类型、密码、交易金额、交易手续费、日期时间、商户代码、2磁3磁数据、交易序列号等,把所有能够总结出来的都总结起来不过100个左右的数据。那我们可以首先简单的设计ISO8583,定义128个字段,将所有能够考虑到的类似上面提到的“帐号”等金融数据类型,按照一个顺序排起来,分别对应128个字段中的一个字段。每个数据类型占固定的长度,这个顺序和长度我们都事先定义好。这样就简单了,要发送一个报文时,就将128个字段按照顺序接起来,然后将接起来的整串数据包发送出去。 任何金融软件收到ISO8583包后,直接按照我们定义的规范解包即可,因为整个报文的128个字段从哪一位到哪一位代表什么,大家都知道,只要知道你的数据包是ISO8583包即可,我们都已经定义好了。比如第1个字段是“交易类型”,长度为4位,第2个字段位是“帐号”,为19位等等。接收方就可以先取4位,再取接着的19位,依次类推,直到整个数据包128个字段都解完为止。 其实这种做法真是简单直接,基本上就可以满足需要了。不过我们有几个问题要思考下: 1、 我怎么知道每个字段的数据类型呢,是数字还是字符? 2、 每个传送的报文都把128个字段都传过去,那网络带宽能够承受得了,有时候我可能只需要其中5个字段,结果多收到了123个无用的字段。 3、 如果我某些字段的长度不固定,属于变长怎么办,因为你现在解包是当作数据包每个字段都是固定的,用C语言解包时直接依靠指针取固定长度的一串字符做为一个 字段。 我们来一一解决这些问题。 第一个问题简单,我在定义ISO8583时除了定义每个字段表示什么,还规定其内容是数字或是字符等即可。考虑可能出现的类型不过有以下几种:字母、数 字、特殊字符、年月日等时间、二进制数据。比如我对128个字段中的“商户类型”字段定义其长度是15,同时定义其类型为字母。再精细点,如果“商户类型”里面的数据同时包括数字和字母呢?那我们就定义其类型为字母也可,为数字也可,即一个字段可以同时属于多个类型。 第二个问题稍微复杂点。其本质就是如果我只传128个字段的5个字段,接收方怎么知道我传了哪几个字段给它了。要是我们把剩下的123全部填成0或其他特殊标识,标明该字段不需要使用?这种处理方法没有半点用处,没有解决网络带宽的本质问题,还是要传128个字段。 换个思路,我在报文前面加上个包头,包头里面包含的信息能够让别人知道只传了5个字段。怎样设计这个包头,可以这样,我 们用16个字节,即128个bit(一个字节等于8bit)来表示128个字段中的某个字段是否存在。每个bit在计算机的二进制里面不是1就是0,如果 是1就表示对应的字段在本次报文中存在,如果是0就是不存在。这样好了,如果别人接收到了ISO8583报文,可以先根据最前面的报文头,就知道紧接着报 文头后面的报文有哪些字段,没有哪些字段了。比如,我要发送5个字段,分别属于128个字段中的第2、3、6、8、9字段,我就可以将128bit的报文 头填成011001011000000000………..,一共128个bit,后面就全是0了。注意其中第2、3、6、8、9位为1,其他都为0。 有了这个128bit的报文头,我们就可以只发送需要的5个字段了。怎样组织报文?先放上这128bit,即16个字节的头,然后在头后面放2、3、6、 8、9字段,这些字段紧挨在一起,3和6之间也不需要填上4、5这两个字段了。接收方收到这个报文,它会根据128bit的报文头来解包,它自然知道把第 3个字段取出后,就直接在第3字段的后面取第6个字段,每个字段的长度在ISO8583里面都定义好了,很轻松就把数据包解出来了。 这下好了,为了解决上面的第二问题,我们只是在报文中增加了16个字节的数据,就轻松搞定了,我们把这16个字节称为bit map,即位图,用来表示某个位是否存在。不过我们再稍微优化一下,考虑到很多时候报文不需要128个字段这么多,其一半64个字段都不一定能够用完。那 我可以将报文头由128bit减到64bit,只有在需要的时候才把剩下的64bit放到报文里面,这样报文长度不又少了8个字节吗? 是个好主意。我们把ISO8583的128个字段中最常见的都放到前64个字段中,那我们可以将处理缩小一倍。这样我一般发送报文时只需发送64bit, 即一个字节的报文头,再加上需要的几个字段就可以了。如果有些报文用到64到128之间的字段呢?这个也好办,我把64bit报文头的第一位bit用来代 表特殊含义,如果该bit为1,则表示64bit后面跟了剩下的64bit报文头;如果第一位bit为0,则表示64bit后面没有跟剩下的64bit报 文头,直接是128个字段中的报文了。那们,接收方会判断一下报头的第一个bit是1还是0,从而知道报文头是64bit还是128bit了,就可以做相 应处理。因为报文头第二个64bit属于有时候有,所以我们叫它Extended bit map扩展位图,相应的报文头最开始的64bit我们叫它Primary bit map主位图。我们直接把扩展位图固定放到128个字段的第一个字段,而主位图每个数据包都有,就强制性放在所有128个字段的前面,并不归入128个字 段中去。 第三个问题可以考虑这样解决。比如第2个字段是“帐号”,是不定长的,可能有的银行帐号是19位,有的是17位等。我们定ISO8583规范时可以规定第 2个字段是25位,这下足够将19和17的情况都包含进来,但是如果以后出现了30位的怎么办?那我们现在将字段定为100位。以后超过100位怎么办, 况且如果你只有19位的帐号,我们定义了100位,那81位的数据不是浪费了网络的带宽。看来预先定义一个我们认为比较大的位数是不太好的。 我们这样,对于第2个字段“帐号”,在字段的开头加上“帐号”的长度。比如帐号是0123456789,一共10位,我们变成100123456789, 注意前面多了个10,表示后面的10位为帐号。如果你接触过COM里面的BSTR,应该对这种处理比较熟悉了。接收方收到该字段后,它知道ISO8583 规定第2个字段“帐号”是变长的,所以会先取前面的2位出来,获取其值,此时为长度,然后根据该长度值知道应该拷贝该字段后面哪几位数据,才是真正的帐 号。如果你觉得长度如果只有两位最多只能表示99位长,不太够,我们也定义可以允许前面3位都为长度的变长字段,这样就有999位长,应该够了吧。在规范 里面如果我定义某个字段的属性是“LLVAR”,你注意了,其中的LL表示长度,VAR表示后面的数据,两个LL表示两位长,最大是99,如果是三位就是 “LLLVAR”,最大是999。这样看我们定义的ISO8583规范文档时直接根据这几个字母就理解某个变长字段的意思了。 该解决的几个问题到这里都解决了,我们来回顾下自己设计的ISO8583规范。其实没有什么,无非是把金融行业可能出现的数据分门别类,排好顺序,接着把 它们连接起来,组成一个报文发送出去而已。其中针对该报文的设计进行了一些优化,引入了bit map位图的概念,也算是一个不错的想法。 剩下的工作就简单了,我们就直接收集金融行业可能出现的数据字段类型,分成128个字段类型,如果没有到128个这么多就先保留一些下来,另外考虑到有些 人有特殊的要求,我们规定可以将128个字段中的几个字段你自己来定义其内容,也算是一种扩展了。 这样,最后我们就得到了ISO8583规范的那张字段描述表了。想要详细的知道每个字段的含义直接对着表看就可以,比较简单 附个样例解析 ISO8583报文如下(十六进制表示法): 60 00 03 00 00 60 31 00 31 07 30 02 00 30 20 04 C0 20 C0 98 11 00 00 00 00 00 00 00 00 01 00 03 49 02 10 00 12 30 62 25 82 21 12 99 63 01 5D 15 11 10 10 00 00 35 36 38 35 32 33 31 34 32 33 35 32 31 34 35 32 36 38 35 39 32 33 36 31 35 36 C6 24 83 4D 36 7E 9E 9E 20 00 00 00 00 00 00 00 00 13 22 00 00 08 00 05 00 36 37 41 32 32 39 39 41 第一步 POS终端上送POS中心的消息报文结构包括TPDU、报文头和应用数据三部分: ——TPDU说明:长度为10个字节,压缩时用BCD码表示为5个字节长度的数值。 ——报文头说明:总长度为12字节,压缩时用BCD码表示为6个字节长度的数值。 ——应用数据说明:一般长度都是4个字节,压缩时用BCD码表示为2个字节的长度的数值。 所以上述报文中前五个字节为TPDU,即60 00 03 00 00 报文头占用六个字节,即 60 31 00 31 07 30 应用数据占用2个字节,即 02 00 也就是"

iOS ViewController点击空白处收起键盘

点击ViewController空白处时收起键盘,可以通过系统的touchesBegan方法实现,具体如下: Objective-C 版 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; } Swift 版 // 收起键盘 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { self.view.endEditing(true) }

HTML中图片位置及大小的控制

经过一些思考和突发奇想,我发现有些时候,在HTML中,如果将三张图片放在一行,那么如果将网页缩小,还会在一行吗。 现在有两种方法: (1)用table <table><tr><td></td></tr></table> 这种用法可以有效地使几张图片放在一行,要是缩小页面,将会有移动的框出现,图片大小不变,但是仍然在一行。 (2)用比例 我们可以设置图片的比例, 比如:width=”60%”,这和上面的结果不同,图片会随着窗口的大小变化而变化。而如果用width=”600px”,那么如果图片大于窗口大小,其他图片就可能不在这一行了。 比如: <center> <img src="http://d.hiphotos.baidu.com/zhidao/pic/item/8b82b9014a90f603f0b9295d3b12b31bb051ed9b.jpg" width="10%" height="10%" /> <img src="http://pic45.nipic.com/20140803/10622095_184333388101_2.jpg"usemap="#Map"width="60%"> <map name="Map"> <area shape="rect" coords="442,155,825,337" href="http://www.baidu.com"> <area shape="circle" coords="248,440,162" href="0005.html"> <area shape="poly" coords="886,76,884,76,894,85,885,74,883,73,883,73" href="#"> <area shape="poly" coords="883,76,954,63,945,140,899,139,909,147,892,135,891,130,886,121" href="about:cehome?from=extra_start"> </map> <img src="http://d.hiphotos.baidu.com/zhidao/pic/item/8b82b9014a90f603f0b9295d3b12b31bb051ed9b.jpg" width="10%" height="10%" /> </center> 欢迎大家加入QQ群一起交流讨论, 「吟游」程序人生——YinyouPoet

Sql的decimal、float、double类型的区别

三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有效位) decimal:数字型,128bit,不存在精度损失,常用于银行帐目计算。(28个有效位) 按存储的范围进行排序 float(real) double decimal(numeric) decimal的详细介绍 decimal(a,b) 参数说明 a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38。 b指定小数点右边可以存储的十进制数字的最大个数。小数位数必须是从 0 到 a之间的值。默认小数位数是 0。 备注 DECIMAL数据类型用于要求非常高的精确度的计算中,这些类型允许指定数值的精确度和计数方法作为选择参数。精确度在这里是指为这个值保存的有效数字的总个数,而计数方法表示小数点后数字的个数。例如,语句DECIMAL (5,2)规定了存储的值将不会超过5位数字,开且小数点后面有2位数字。 实例 SQL 代码 复制 float f = 345.98756f;--结果显示为345.9876,只显示7个有效位,对最后一位数四舍五入。 double d=345.975423578631442d;--结果显示为345.975423578631,只显示15个有效位,对最后一位四舍五入。 --注:float和double的相乘操作,数字溢出不会报错,会有精度的损失。 decimal dd=345.545454879.....--可以支持28位,对最后一位四舍五入。 --:当对decimal类型进行操作时,数值会因溢出而报错。 总结 数值存储范围越小的精度越高,存储数值范围越大,精度就越不准确,如果存储正常金额的情况下,使用money,好处在于可以存储不指定的小数点位数的数值,比较真实。如果对于既要求精度,又固定小数点位数的数值存储,采用decimal(numeric),优点在于可以自定义小数点位数,精度高。如特殊情况,如数值范围巨大只能用float(real)类型了,此类型一般不提倡使用。 文章转载自:http://www.studyofnet.com/news/214.html

如何使用ELK来监控性能

每当我解决一些应用性能问题的时候,我常常会看到一个服务由于高的CPU利用率而使得一台或者多台服务器运行变得非常缓慢。这也许意味着它因为高负载而导致资源缺乏,但是通常情况下这其实是代码有bug,一个异常或者一个错误的流程导致过多占用了系统资源。为了把这些问题找出来,我不得不在NewRelic/Nagios和ELK之间查看信息。 所以我确信我需要有一个单一的管理面板来查看从各个应用,操作系统以及网络设备上收集来的事件组合而成的性能指标 为了使用ELK来监控你平台的性能,你需要集成一系列的工具。Probes是必须包含的组件,它运行在各个主机上用来收集各种系统性能指标。然后,采集的数据需要发送给Logstash,然后在Elasticsearch中进行聚集,最后由Kibana转换成图形。最终,软件服务操作组成员使用这些图形展示系统性能。在这篇文章中,我将分享我们如何建构我们的ELK软件栈来监控服务的性能。 1. 收集和传送 收集 在收集和传送数据到Logstash中的第一个步骤,我们使用一个名为 Collectl 的工具。该工具来自于一个开源项目,它包含的大量的选项允许系统管理员从多个不同的IT系统中获取各种指标,并且运行保存这些数据供以后分析。我们使用它来生成,追踪,以及保存指标数据,例如网络吞吐量,CPU的磁盘IO等待时间,空闲的内存,以及CPU的空闲时间(指出过度/未充分使用计算机资源)。它也常被用于监控其他类型的系统资源,例如inode的使用以及打开的socket数量。 Collectl命令输出样例 最后,Collectl使用指定格式(in plot format)将采集的指标输出到一个日志文件中。该开源项目知道如何收集信息但是它并不会自动发送数据到ELK软件栈中。 使用一个Docker容器 我们把Collectl封装到了一个Docker容器中来获取一个Docker镜像,该镜像会包含了数据采集和数据发送的基本软件。我们使用版本4.0.0的Collectl以及下面提到的配置,这样可以避免一系列的问题: —— 为了避免数据在容器中过载,我们只保存了当天的数据。更久的数据都是维护在ELK软件栈中,因此你无需担心在容器的日志中保存所有的数据导致的问题。 —— Collectl可以以指定的时间周期收集各种采样数据,当它会用不同的时间周期把数据持久到磁盘。这被称为刷新周期。如果数据每秒钟都被刷新到磁盘那么你可以得到近乎实时的数据。不过例如对于一个30秒的采集间隔,那么选择一个十分激进的采样周期不是必须的。一个输出格式化器会用于输出指定格式(a plot format)的输出,默认它会在每一行输出多个值,每个值用空格分开。 Collectl配置文件看上去类似下面: DaemonCommands = -f /var/log/collectl/performance-tab -r00:00,0 -F1 -s+YZ -oz -P --interval 30 PQuery = /usr/sbin/perfquery:/usr/bin/perfquery:/usr/local/ofed/bin/perfquery PCounter = /usr/mellanox/bin/get_pcounter VStat = /usr/mellanox/bin/vstat:/usr/bin/vstat OfedInfo = /usr/bin/ofed_info:/usr/local/ofed/bin/ofed_info Resize=/usr/bin/resize:/usr/X11R6/bin/resize Ipmitool = /usr/bin/ipmitool:/usr/local/bin/ipmitool:/opt/hptc/sbin/ipmitool IpmiCache = /var/run/collectl-ipmicache IpmiTypes = fan,temp,current 使用RSYSLOG RSYSLOG是另一个容器组件。它用来从日志文件中提取数据,并且发送数据到ELK软件栈中。为了让Logstash专注于需要字段而不是所有的数据上,这里建议使用RSYSLOG在日志里增加一些元数据来对日志进行筛选。这里可以在数据发送前对指标进行过滤或者增加一些信息比如实例名称以及IP地址。附加上了时间戳后,这些信息可以被发送到Logstash。 一些注意点 在本步骤,有两个问题需要注意: 1 - 时间戳: 首先,Collectl并不在采集的数据中输出它的时间戳。因此如果你不同的主机运行在不同的时区,它们在你的ELK里面并不会对齐。为了解决这个问题,我们需要查询容器当前运行的时区,然后设置相应的时间戳。 2 - 遵循Collectl日志文件名: 另一个复杂的问题是Collectl输出数据到一个文件中,但是该文件名不是固定不变的。仅仅文件名的前缀是可以自定义的,然后Collectl自动在文件名上加上了当前日期。这个问题导致RSYSLOG不能通过文件名来监视文件,当日期切换时文件名也会改变。我们可以用最新版本的RSYSLOG —— 版本8来解决它,但是这里我假设大多数用户还没有用上这个版本。我们创建了一个很小的脚本,它调用了老版本的RSYSLOG,该脚本在容器里运行了一个定时的任务,该任务会链接一个指定的名称的文件名到一个固定的日志文件名上。然后SYSLOG只中那个固定日志文件中提取数据,即便该文件链接的目标文件改变了也没有关系。这就像一个指针,它在一定的时间下总是指向正确的Collectl日志文件。

构造函数调用和复制构造函数调用

class MyClass { int value; public: MyClass(int i=10) { value = i; cout << "Constructor called." << endl; } MyClass( MyClass& p) { p.value = 11; value = p.value; cout << "Copy constructor called" << endl; } void Print() { cout << "The Value is " << value << endl; } ~MyClass(){ cout << "Destructor called" << endl; } }; int main() { MyClass obj1; obj1.Print(); MyClass obj2(obj1); obj2.Print();

Nginx 本机 80 访问正常而同局域网内其他机器无法访问的问题

今天遇到奇怪的问题,Nginx 配置和启动正常,uWSGI 配置和启动也正常,本机打开浏览器访问本机 IP:80 正常,但同一个局域网内的其他机器通过 IP:80 访问就提示无法连接。着实困扰了一阵子。 经过排查,发现是有别的服务启动后占用了 80 端口,而本机访问时因为走本地环回,所以其实本质上没有过 80 端口。 所以要么把 Nginx 配置中的端口改掉,要么把占用 80 端口的服务停掉,就可以解决次问题。

基于CNN的文字识别--总结

一 网络结构 文字识别(非手写体)相对容易,CNN网络结构基本4层就可以跑出较好的结果;模型收敛也较为容易,加上dropout收敛也很快,一两个小时就能收敛到90%多(titanX). 二 训练样本 当然,人力、财力、时间有保证的话,收集实际样本效果肯定会好些,没这些条件的话,人工生成样本也不错。一个字几百上千个样本基本靠谱,但是,要注意样本最好要hard。 三 经验 1 由于验证集、训练集都是自己生成的,so,通过验证集判断模型有没有过拟合就不靠谱了。。。模型熟练到98%后,就开始过拟合,而验证集准确率还在上升。。so,验证集还是人工标注生成吧 2 在训练时,我把softmax输出类别设置为字符类别数,得到提取字符特征的模型,同时也拿来对字符分类;用模型提取的特征,当图像文字/非文字进行判断(方法包括训练分类器,或是直接在网络后面用softmax输出值进行阈值判断,小于阈值认为是非文本)时,发现效果不是太好。可能是特征提取的有问题,《Deep Features for Text Spotting》文章中在模型训练时,有一个背景类别,这样提取出的特征可能对文字、非文字区分性更强些?下一步可以试试。 3 犯了一些低级错误,有时候越怕麻烦越麻烦,事情还是得一步一步踏踏实实的去做,文章还是得一篇篇去读,算法还是得一个个去啃,代码还是得一行行去写,工资还是得一块块去长。。额。。我排比不下去了,哈哈~

IE get请求传参中文乱码

1.IE中 get请求传参中文乱码: js: _td=_td+"<a href='/noa/rppbase/uploads_dowloadUploadTemplate.action?" + "filePath=" + _tem[k].templateurl + "&" + "fileName=" + encodeURI(encodeURI(_tem[k].templaterealname)) + "'>"+_tem[k].templaterealname+"</a>"; action: String tempName = URLDecoder.decode(this.fileName, "UTF-8"); this.fileRealName = new String(tempName.replace(" ", "_").getBytes("gbk"), "ISO8859-1"); 2.json传参中文乱码: js: var jsonFileInfo = { "filePath" : filePath, "fileName" : fileName }; "<a href='/noa/rppagingprogress/commitAging_downUpload.action?jsonFileInfo=" + JSON.stringify(jsonFileInfo)+ "'>" + fileName +"</a></td>" action: this.fileName = new String(upload.getFileName().getBytes("gbk"), "ISO8859-1");

Tomcat 内存溢出,堆栈配置各种调整

部分参说明: -server:一定要作为第一个参数,在多个CPU时性能佳 -Xms:初始Heap大小,使用的最小内存,cpu性能高时此值应设的大一些 -Xmx:java heap最大值,使用的最大内存 -XX:PermSize:设定内存的永久保存区域 -XX:MaxPermSize:设定最大内存的永久保存区域 -XX:MaxNewSize: +XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。 -Xss:每个线程的Stack大小 -verbose:gc 现实垃圾收集信息 -Xloggc:gc.log 指定垃圾收集日志文件 -Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一 -XX:+UseParNewGC :缩短minor收集的时间 -XX:+UseConcMarkSweepGC :缩短major收集的时间 提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。 tomcat 的jvm 内存溢出问题的解决 1、首先是:java.lang.OutOfMemoryError: Java heap space 解释: JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。 提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。 提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 解决方法:win下 手动设置Heap size 修改TOMCAT_HOME/bin/catalina.bat,在“echo ”Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行: set JAVA_OPTS=%JAVA_OPTS% -server -Xms800m -Xmx800m -XX:MaxNewSize=256m 2、其次是:java.lang.OutOfMemoryError: PermGen space 原因: PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

MSSqlserver 恢复sa密码及 删除builtin\administrators后恢复

BUILTIN是built in 是创建Windows时候的Administrator内建账号。当删除(drop)builtin\administrators 后,Windows验证方式将无法登录sqlserver数据库。但当你忘记SA密码是基本只能重置SA密码来找回你的sysadmin用户重建builtin\administrators。 该方法适用绝大多数MSsqlserver版本。 故本文旨在两个目的: 一、如何通过单用户模式找回SA密码; 二、如何恢复builtin\administrators账号,恢复windows验证方式登录mssql数据库。 一,找回SA密码 1) Run as administrator 打开comandline,执行如下停库命令: net stop mssqlserver 其他服务可停可停,建议全部停掉,确保没有其他任何用户或程序尝试连接数据库(如是vmware可将网卡禁用在console端操作),否则会提示如下错误: Login failed for user. Reason: Server is in single user mode. Only one administrator can connect at this time 2)单用户模式打开数据库 net start mssqlserver /m 3)更改sa密码 sqlcmd -S msserver_hostname -E //命令行连接数据库, - S msserver_hostname为数据库主机名 ALTER Login sa enable //(如果sa没有启用,需要重新开启) go ALTER LOGIN [sa] WITH PASSWORD='123456' //123456 为新密码 go 注,如果errorlog中提示Login failed for user 'sa'.

tez跑任务报错

tez跑任务报错: java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2570) at java.lang.Class.getMethod0(Class.java:2813) at java.lang.Class.getMethod(Class.java:1663) at org.apache.hadoop.util.ProgramDriver$ProgramDescription.(ProgramDriver.java:59) at org.apache.hadoop.util.ProgramDriver.addClass(ProgramDriver.java:103) at org.apache.tez.examples.ExampleDriver.main(ExampleDriver.java:47) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.hadoop.util.RunJar.run(RunJar.java:221) at org.apache.hadoop.util.RunJar.main(RunJar.java:136) Caused by: java.lang.ClassNotFoundException: org.apache.tez.dag.api.TezConfiguration 暂未解决,感觉是tez的rpm包打的有问题。 最后问题解决:发现hadoop-classpath中的tez的路径未加入。 hadoop-classpath:/usr/lib/tez/:/usr/lib/tez/lib/即可

Android音量控制曲线

本文介绍了android音量的控制曲线的计算方法。 由于人耳对声音的听感具指数曲线型,也就是对小音量时比较敏感,随着声音的加大其听感随之变的不敏感,其变化近似指数函数曲线的形式。为了使听感变的近似直线的变化,人们在实践中就采用了音量变化近似对数式曲线型的电位器来实现这个目的。对比法产生音量控制曲线与最终扬声器输出的声压有关,当然您也可以根据扬声器的输出功率来进行比对,但功率终究不如电压来的方便。音量调节框的UI滑动条的刻度是线性的,这样就给我们生成音量控制曲线打下了很好的对比基础。下面我们就来通过一个音量调节的场景来分析Android是如何控制音量的。 首先,我们按音量调节键使得media音量逐级增加到最大。STREAM_MUSIC流的音量分为15级,通过AudioManger的handleKeyDown函数调用adjustSuggestedStreamVolume设置,一路找下去,发现在AudioService中adjustSuggestedStreamVolume然后调用adjustStreamVolume,通过消息MSG_SET_SYSTEM_VOLUME调用setSystemVolume,转到AudioSystem中的setStreamVolumeIndex,再通过jni层调用本地层的AudioSystem调用AudioPolicymanagerService,最后到AudiopolicyManagerBase的setStreamVolumeIndex,接下来的由checkAndSetVolume调用computeVolume,马上就要到真相大白的时候了。volIndexToAmpl函数时真正计算音量的地方,我们一起来分析这个函数 // 在intel的CherryTrail平台的android 6.0 版本上,这个函数位置是:/frameworks/av/services/audiopolicy/engineconfigurable/src/Stream.cpp 里 float AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc, int indexInUi) { device_category deviceCategory = getDeviceCategory(device); const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory]; // the volume index in the UI is relative to the min and max volume indices for this stream type int nbSteps = 1 + curve[VOLMAX].mIndex - curve[VOLMIN].mIndex;//计算预置的曲线区间的范围,这里是(1-100) ALOGI("VOLUME vol indexInUi=%d, nbSteps=%d, mIndexMin=%d, mIndexMax=%d",indexInUi,nbSteps,streamDesc.mIndexMin,streamDesc.mIndexMax); int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) / (streamDesc.

Android gitignore文件解析

由于网上各种版本的ignore文件,很多人和我一样都是拿来就用的。不知道其原理,我乘着有空学了下gitIgnore的写法,同时将我经常用的Android项目的gitIgnore文件拿来分析学习下。 我将分析都写在注释里了,看看就懂啦~ # Built application files # 忽略所有apk文件和ap_文件。 *.apk *.ap_ # Files for the Dalvik VM # 忽略所有dex文件 *.dex # Java class files # 忽略所有class后缀的文件 *.class # Generated files # 忽略所有bin和gen文件夹中的所有文件 # 注意这里是指项目中所有bin和gen文件夹 bin/ gen/ # Gradle files # 忽略所有.gradle和build文件目录下的所有文件 .gradle/ build/ # Local configuration file (sdk path, etc) # 忽略所有local.properties文件 # 这些文件存放有sdk路径、账目密码等,这些是不会记录到git中的。 # 所以有一些保密的东西会被写到这个文件中,确保不会再VCS中泄密。 local.properties # Proguard folder generated by Eclipse # 忽略所有proguard文件目录下的所有文件 proguard/ # Log Files # 忽略所有log文件 *.

【重点推荐】iOS开发之芝麻信用SDK的超详细使用教程

其实每一个第三方SDK的使用都差不多,看着官方给的开发文档和Demo就能依样画瓢自己做出来。我只是希望帮助一下刚入行不久的新人。 先附上官方文档的地址:芝麻信用iOS开发文档 一、先做一些必备的工作 由于需要导入的Framework比较多,先创建一个Frameworks分组(分组和文件夹可不一样哦) 1. 将资源bundle导入工程 H5Service.bundle Poseidon.bundle 直接把下载到的这两个文件拖进Frameworks分组中 2. 向工程中导入SDK Framework文件 ZMCreditSDK.framework ZMDependUponSDK.framework 注意1:如果商户引入支付宝钱包SDK,则不需要再引入ZMBuildUponSDK.framework, 因为这样可以解决相同类库冲突的问题 注意:这两个文件导入之前一定要把他复制到你的项目中去,一般就放项目根目录下就行,跟xcodeproj文件在同一目录下 这里需要选择Add Others,然后会弹出文件选择框,把刚刚复制到项目根目录下的这两个framework选进来就行了 (第三步中的其他依赖库,都是系统的,直接search就行了,第三步就不贴图了) 3. 导入其他依赖库 SDK中依赖了其他基础库来保证正常运行,请添加如下依赖库: MobileCoreServices.framewrok CFNetwork.framework MessageUI.framework EventKit.framework AssetsLibrary.framework CoreMotion.framework Libz.dylib (Xcode 7 之后是libz.tbd) SystemConfiguration.framework CoreTelephony.framework 二、开始使用芝麻信用SDK 自己先把流程走一遍,一切都会变的很容易。(流程见下图) 首先,在AppDelegate里面来注册应用: [[ALCreditService sharedService] resgisterApp]; 当然,在AppDelegate中和请求芝麻信用分数的Controller中肯定也都需要引入头文件 #import <ZMCreditSDK/ALCreditService.h> 接下来就是正式使用芝麻信用SDK了 ①我们把用户的信息(姓名、手机号、身份证号码)通过APP传给公司的服务器(这一步其实基本不属于芝麻信用的使用范畴,现在哪个APP获取不到用户的个人信息?!我们这里其实只传了姓名和身份证号码,其实有了身份证号码,芝麻信用自然就能锁定到那个唯一的人)只要能够获取到姓名和身份证号码,服务器那边就能传给我们一个经过加密的param和一个经过加密的sign 注意2:界面跳转是基于navigationController的push功能,并且使用的是系统的nav bar,如果商户端有对nav bar作自定义,请在调用SDK之前,进行nav bar的调整。 - (void)buttonAction:(UIButton *)button { // ①把用户数据传给服务器,即传入参数(字典) //(如果后台从别的页面已经获取到用户的这些数据了,此处也可以不传参数,这就看你跟后台怎么商量了;IDCardNumber和userName是后台给你的,不是固定死的) NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"18位身份证号码", @"IDCardNumber", @"用户姓名", @"userName", nil]; // 创建网络请求管理对象 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // 申明返回的结果是json类型 manager.

Android5.0之NavigationView的使用

导航菜单的制作方式多种多样,网上也有各种炫酷效果的具体实现方式,那么今天我主要是想来说说Google在Android5.0之后推出的NavigationView的具体使用方式。 NavigationView在很多App上都已经可以看到其效果图,国内的比如知乎(侧拉菜单滑出来的那一部分属于NavigationView),如下图: 还有Google自己的那些app,也基本全都采用了NavigationView,如下图,分别是Gmail、Google Map以及Google Play: OK,看完了图,接下来我们就来说说这个NavigationView吧。 1.NavigationView是什么 long long ago,我们做抽屉菜单的时候,左边滑出来的那一部分的布局都是由我们自己来定义的,自己写的话,花点时间也能做出来好看的侧拉菜单,但总是要耗费时间,于是Google在5.0之后推出了NavitationView,就是我们左边滑出来的那个菜单。这个菜单整体上分为两部分,上面一部分叫做HeaderLayout,下面的那些点击项都是menu,这样的效果如果我们要自己写肯定也能写出来,但是没有必要,既然Google提供了这个控件,那我们就来看看这个控件要怎么用吧。 2.NavigationView怎么用 和普通的侧拉菜单制作方式一样,首先所有的东西还是都放在一个DrawerLayout中(如果你对DrawerLayout的使用还不熟悉,请参考这篇文章使用DrawerLayout实现侧拉菜单),只不过这次我们把左边滑出菜单的布局用一个NavigationView来代替,代码如下: <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="org.mobiletrain.drawerlayout.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="主页面"/> </LinearLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="left" android:fitsSystemWindows="true" app:headerLayout="@layout/header_layout" app:menu="@menu/main"></android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>OK,下面我来分别解释一下这里边几个属性的含义: 1.android:layout_gravity="left"属性表示该View是左边的滑出菜单,这个属性的含义不用多说,这是DrawerLayout使用方式中的知识点。 2.app:headerLayout="@layout/header_layout"表示引用一个头布局文件,这个头就是我们在上面看到的那个背景图片,包括背景图片上面的显示用户名的控件等等。 3.app:menu="@menu/main"表示引用一个menu作为下面的点击项 OK,那我们再来看看头布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="200dp" android:orientation="vertical"> <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/p1"/> </LinearLayout> 再来看看menu文件: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/favorite" android:icon="@mipmap/ic_launcher" android:title="收藏"/> <item android:id="

python 读取中文文件名/中文路径

python直接读取中文路径的文件时失败,可做如下处理: inpath = 'C:\Users\chenjunli\PycharmProjects\mytest1\cc.txt' uipath = unicode(ipath , "utf8") 然后用"uipath"经过编码后的路径去open()即可: fin = open(uipath)

学习笔记:解决 warning C4566

#include "stdafx.h" #include <string> #include <iostream> using namespace std; int main() { //warning C4566: 由通用字符名称“\u00E4”表示的字符不能在当前代码页(936)中表示出来 //ä的UNICODE编码是 \u00E4, 在中文环境下,编译器不能把它转为GBK. 因为GBK中没有这个字符对应的编码。 //cpp源文件里,ä可以按照utf-8格式或ucs16保存,这就是问什么关闭项目,重新打开后,ä没有丢的原因。 //VS20XX IDE会从文件BOM头中识别当前源文件的编码方案。对于uft-8,bom=EF BB BF //用ultra-edit打开生成的exe,用二进制模式查看。======...会很容易发现,查看应该是ä的位置,实际是? (0x3F) //调试方式下,查看buff的值,也会看到ä的位置上,内存值是0x3F( 就是一个'?') char buff[] = "=========================ä"; //增加下面这句也照样会出现warning C4566 //setlocale(LC_ALL,"chs"); //如果要解决C4566问题,办法是在“控制面板”->“区域与语言”->“更改系统区域设置” //ä是德文的一个字符,所以把“当前区域设置”成德国。经过设置和系统重启生效,发现buff中ä被编码为0xe4, 编译生成exe正常。 //在VS20XX环境下测试一下,看能否输出正常。经测试不正常。 //然后,从cmd中执行exe。先打开cmd,调用chcp命令查询当前code page,确保是德语 code page 1252 //(如果console在启动后不是你希望的code page,则在这面这个注册表中,修改code page // [HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]) // ( 如果不想改注册表,则每次打开cmd后,执行chcp 1252命令,转入德文环境) //然后执行 本程序XX.exe. 输出正常。 //看来,从VS20XX中用调式代码的方式执行,与从cmd(shell)中启动exe,有很大差异。 //这个差异的原因,还需要再研究学习。 cout << buff << endl; //如果在程序中,用硬编码的方式强制更改为德文环境,输出正常。 //这个办法,可以不用改注册表,也不用从cmd中执行前执行chcp 1252。 setlocale(LC_ALL,"German"); cout << buff << endl; system("

关于SSD HMB与CMB

关于Controller Memory Buffer(CMB) 每块SSD上,不管是SATA还是PCIE口的,都会有一定量的DRAM来做数据缓存。但是,这个数据缓存对Host端是不可见的,也就是说,Host端的代码是不可能直接使用访存指令访问到这块数据缓存的,这块内存空间并没有被映射到Host物理地址空间中。 我们知道,Host端的程序只能通过访问某个或者某些物理地址从而与SSD控制器通信。通常,Host端的驱动程序会将由上层协议栈准备好的IO指令及数据在Host主存中的基地址(也就是指针)采用Stor指令写入到SSD控制器的前端PCIE控制器模块所暴露的寄存器中,SSD控制器接收到该指针,便可以从Host主存中取回对应的指令及数据从而执行。SSD控制器的这些寄存器会被映射到Host物理地址空间中的某处,该动作由host端PCIE bus driver在枚举PCIE设备之后即执行。底层细节和过程冬瓜哥就不过多描述了。 可以看到,SSD控制器只向host端暴露了很少量的寄存器存储空间,并未将其内部的数百兆甚至上GB的DRAM空间映射到host物理地址空间。而且,驱动程序先把对应的指针通知给SSD控制器,然后SSD控制器需要主动从Host主存取指令和数据。有人可能会想,为何驱动程序不直接将指令及数据写入到SSD的DRAM中呢?原因是CPU如果把这事都自己干了,那就忙不过来了,会深陷到Load/Stor指令移动数据,其他活就没法干了。SSD控制器上有个DMA模块,在收到指针之后,DMA模块会主动读取host主存,此时host CPU可以做其他事情。 但是如果CPU将整条指令而不是指针直接写到SSD端的DRAM的话,并不耗费太多资源,此时能够节省一次PCIE往返及一次SSD控制器内部的中断处理。于是,人们就想将SSD控制器上的一小段DRAM空间映射到host物理地址空间从而可以让驱动直接写指令进去,甚至写一些数据进去也是可以的。这块被映射到host物理地址空间的DRAM空间便被称为CMB了。 CMB对NNMe Over Fabric场景下非常有用,因为节省了一趟往返,如果外部网络时延较大的话,每笔IO都节省了一次往返,每秒便能增加不少IOPS。 CMB还有另外一种应用场景,在5月19日的中国云计算大会上冬瓜哥有个分享,会向大家介绍,这里就不多说了。 关于Host Memory Buffer(HMB) 有些SSD产品为了节省成本,板载DRAM很小,或者根本没有。就像有些显卡没有板载显存一样。但是并不表示它们不需要DRAM。它们的DRAM可以与host端的主存共享,也就是分配一块主存用作其DRAM,这些外部设备控制器可以通过PCIE接口访问host端的DRAM。共享显存的模式下,系统bios会直接分割出一块连续的DRAM给显卡使用,此时,host端OS根本看不到这块空间,BIOS会配置系统IO桥上的地址路由表以及地址范围寄存器,从而实现不同访存请求的路由。 NVMe协议中也定义了这种场景,只不过,并非像共享显存那样直接从bios层面分配连续的空间,而是由NVMe驱动在OS所管理的物理地址空间内分配对应容量的RAM给SSD控制器使用,这段空间物理上可以不连续,NVMe驱动将对应的基地址+长度的列表推送给SSD控制器,SSD控制器需要将对应的列表更新到内部的寄存器中用于访存查找。这样,SSD控制器就可以将比如FTL映射表存储到host端的这块RAM中,这也就意味着,每一笔IO请求发送到SSD之后,SSD控制器需要通过PCIE来访问host端的这块RAM从而提取出映射表中对应的条目来查找对应IO目标逻辑地址所被映射到的物理地址,也就意味着每一笔IO都需要产生更多的PCIE流量,时延就会大增。 当主机突然掉电之后,host端的这块RAM中数据就会丢失。重启之后,SSD需要从Flash Page中保存的元数据重构出这张大表,再次写入host端的ram。只不过,这个动作只有OS启动之后,NVMe驱动加载之后,才能执行,因为每次启动NVMe分配的这块RAM对应物理地址可能都不同。这会产生一个问题,如果用该SSD当做启动盘的话,重启之后bios阶段是无法给SSD分配host内存的,即便分配了,OS也不会认,除非改OS的内存管理部分。此时,SSD必须先使用其板载的小容量SRAM/DRAM,性能会比较差。OS启动后再后台继续重构FTL表。 HMB使用场景比较受限制,所以目前还没有出现使用HMB机制的SSD。 其他相关阅读(点击可直接进入): 《 【冬瓜哥画PPT】浅谈闪存控制器架构 》 《 【冬瓜哥论文】浅析固态介质在存储系统中的应用方式 》 《 你绝对想不到的两种高逼格存储器 》 《 【冬瓜哥手绘】大话众核心处理器体系结构 》 《关于SSD元数据及掉电保护的误解 》 《 关于闪存FTL的Host Base和Device Based的误解 》 《帮你梳理一下各种存储协议及接口》 多少赏点吧 Reward people gave a reward

jquery.fn jquery.extend jquery.fn.extend

$.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效。 如扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后面你的每一个jquery实例都可以引用这个方法了. 那么你可以这样子:$("#div").abc(); jQuery为开发插件提拱了两个方法,分别是: jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法。 jQuery.fn.extend(object);给jQuery对象添加方法。 fn是什么东西呢。查看jQuery代码,就不难发现。 复制代码代码如下: jQuery.fn = jQuery.prototype ={ init: function( selector, context ){//.... //...... }; 原来 jQuery.fn =jQuery.prototype.对prototype肯定不会陌生啦。 jQuery便是一个封装得非常好的类,比如我们用语句 $("#btn1") 会生成一个 jQuery类的实例。 jQuery.extend(object); 为jQuery类添加添加类方法,可以理解为添加静态方法。如: 复制代码代码如下: $.extend({ add:function(a,b){returna+b;} }); 便为 jQuery 添加一个为add 的 “静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了, $.add(3,4); //return 7 jQuery.fn.extend(object);对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使用这个“成员函数”。 比如我们要开发一个插件,做一个特殊的编辑框,当它被点击时,便alert当前编辑框里的内容。可以这么做: jQuery代码 复制代码代码如下: $.fn.extend({ alertWhileClick:function(){ $(this).click(function(){ alert($(this).val()); }); } }); $.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效。 如扩展$.fn.abc(),即$.fn.abc()是对jquery扩展了一个abc方法,那么后面你的每一个jquery实例都可以引用这个方法了. 那么你可以这样子:$("#div").abc(); jQuery为开发插件提拱了两个方法,分别是: jQuery.extend(object);为扩展jQuery类本身.为类添加新的方法。 jQuery.fn.extend(object);给jQuery对象添加方法。 fn是什么东西呢。查看jQuery代码,就不难发现。 复制代码代码如下: jQuery.fn = jQuery.prototype ={ init: function( selector, context ){//.

[swift实战入门]手把手教你编写2048(三)

上篇地址:swift实战入门之手把手教你编写2048(二) github地址:https://github.com/scarlettbai/2048.git。 今天给大家带来2048最后一篇,之前已经实现了向游戏区域中随机插入数字块,接下来要做的,就是当我们滑动屏幕时移动及合并数字块以及插入一个新的数字块。本篇的难点就是移动时的算法问题,首先来给大家讲一下算法。 2048的算法实现其实很简单,假如我们当前数字格的格式如下: | |4| | | | | |4| | |2| |2|2| |2| | | | 如果用户选择向上滑动,那么这里我们算法里要做的是,先取出第一列的4个格存为一个数组,对应坐标为[(0,1),(0,2),(0,3),(0,4)],其中对应的值为| | |2|2|,首先对数组进行去除空操作,去除之后数据为:[(0,3),(0,4)],对应值为|2|2|,之后再进行合并操作,合并时我们可以取到数组中原来两个2的坐标以及最终坐标,那么此时我们只要更新存储当前数字块状态的数组以及数字块视图,将之前两个2的地方置空,并在(0,1)处插入一个4即可,之后再继续遍历下一列做同样的操作即可。 这里用户一共有4个操作,上下左右,分别取出对应的行列一行(列)一行(列)的进行处理即可。那么接下来看代码: 首先我们定义几个枚举: //用户操作---上下左右 enum MoveDirection { case UP,DOWN,LEFT,RIGHT } //用于存放数字块的移动状态,是否需要移动以及两个一块合并并移动等,关键数据是数组中位置以及最新的数字块的值 enum TileAction{ case NOACTION(source : Int , value : Int) case MOVE(source : Int , value : Int) case SINGLECOMBINE(source : Int , value : Int) case DOUBLECOMBINE(firstSource : Int , secondSource : Int , value : Int) func getValue() -> Int { switch self { case let .

Ubuntu 14.04 配置 Nginx + uWSGI 托管 virtualenv 下 Flask 应用的一点注意事项

标题很长,本文内容却很简单。在现在的 Python 开发中,虚拟环境是必不可少的,但是有时候,虚拟环境又会给我们带来一些不必要的麻烦或者说坑,比如今天要谈到的 Flask 应用托管的问题。 Nginx + uWSGI 可以说是 Python Web 项目托管的不二之选,当然,如果只是自己开发测试,或者应用在访问量很小的应用上,Gunicorn 甚至 Web 框架自带的 web server 也许就够了,但是我们逃不开会碰到这对王者组合的情况,今天我就遇到了这样的坑。按照官方文档分别配置 Nginx 和 uWSGI 后,使用 uwsgi 的命令语句启动,没有任何问题,但是尝试使用 ini 配置启动 uWSGI 后,则会遇到一直报 502 bad gateway 的错误。 一番排查后——排查过程不表——发现问题所在,我的 uWSGI 安装在了项目的 virtualenv 目录中,然而 ini 配置文件却没有配置虚拟环境目录,而网上现有的博客教程里的 ini 配置都是没有提到这个问题的,所以,我们加上虚拟环境的配置,并且注意,最好加上 plugin = python 这一条配置,当然了,这个需要提前安装,具体如何安装,不是本文重点,暂不赘述了。 所以,我最终的 ini 配置文件内容如下: [uwsgi] plugins = python vhost = true chdir = /home/k/Documents/demo venv = /home/k/Documents/demo/venv #python module to import app = main module = %(app) #socket file's location socket = /home/k/Documents/demo/%n.

iOS之键盘的使用/通知对键盘的监听

一.通知 每一个应用程序都有一个通知中心,专门负责不同对象之间的消息通信,任何一个对象度可以向通知中心发布通知,其他感兴趣的对象可以申请在某一个特定的通知发布的时候(或者在某一个特定的对象发布通知时)接受这个通知. NSNotificationCenter 接受用户的注册,有通知过来时,用户就接收到了通知消息); 所有的通知都封装在NSNotification中; 1. 注册监听 addObserver : 监听者 selector : 接收到通知的时候,调用监听者的方法 name : 通知的名称 object :通知的发布者 注意:如果name 和object同时为空,那么接收所有的通知;一般请情况下name 不为空; 如果name 为空,接收某一个发布者的所有通知; 如果 object为空,接受名称为name 的所有通知; [[NSNotificationCenterdefaultCenter]addObserver:zhangsan selector:@selector(reciveNotification:) name:@"Hunter" object:souhuHunter]; 2. 发布通知 postNotificationNam :必须和注册的时候name 保持一致 object :消息的发布者 userInfo :自定义的消息 [[NSNotificationCenterdefaultCenter] postNotificationName:@"Hunter" object:souhuHunter userInfo:@{@"company":souhuHunter}]; 3.当监听者对象被销毁的时候,一定要从通知中心吧监听者移除掉 - (void)dealloc { // 一定要把监听者移除掉 [[NSNotificationCenterdefaultCenter] removeObserver:self]; } 二. - (void)viewDidLoad { [superviewDidLoad]; // 设置控制器成为tableView的数据源代理 _tableView.dataSource =self; // 设置控制器成为tableView的代理 _tableView.delegate =self; // 每一个cell的高度都是相同 // _tableView.rowHeight = 60;

第九周项目一 阅读程序,写出程序运行结果并理解(1)

/*copyright(c)2016.烟台大学计算机学院 * All rights reserved, * 文件名称:text.Cpp * 作者:舒文超 * 完成日期:2016年4月17日 * 版本号:vc++6.0 * * 问题描述:阅读下面程序,写出运行结果并理解 */ #include <iostream> using namespace std; class A { public: A(){cout<<"A";} ~A(){cout<<"~A";} }; class B { A *p; public: B() { cout<<"B"; p=new A(); } ~B() { cout<<"~B"; delete p; } }; int main() { B obj; return 0; } 运行结果: BA~B~A B:声明B类的“obj”执行B类的构造函数,输出“B” A:在执行B的构造函数时,给A类型的*p分配动态内存,从而执行A类的构造函数,输出“A” ~B:程序运行结束,释放obj的内存,输出“~B” ~A:在执行B类的虚构函数时执行A的虚构函数,输出“~A” 

系统从win7更新到win10没有声音(扬声器一直显示未插入)

今天将电脑的系统从win7更新到了win10,本来很期待新的系统,但是更新完就遇到许多问题,比如在win7系统下,耳机插入就可以识别,可以听到声音,但是更新至win10后发现怎么搞都没有声音,在网上看了很多解决办法都没有解决我的问题。(我的是台式机,华硕的主板,不知道其他会不会出现相同的问题)一开始我以为声卡驱动的问题,后来发现不是的,有人说华硕声卡只有win8.1的,可以兼容win10使用,但是我下载win8.1声卡驱动,可惜的是并不能安装成功,后来不停的摸索在百度的海洋中寻找答案,终于找到一个方法我试了之后发现有效果了,于是乎我就抛弃了很多之间所谓的声卡驱动问题的解决办法,写这个博客是记录自己,也是为了方便和我遇到同样的问题的人,希望我的解决办法能给你带来帮助。 第一步: 在搜索框中输入“控制面板”,出来以下显示: 第二步: 选择硬件和声音,出现以下显示: 第三步: 选择Realtek高清晰音频管理器,出现以下显示: 我画圈圈的三个是成功解决之后出现的,在未经过以下步骤之前,只有一个显示(没有扬声器和麦克风连接成功显示) 第四步: 选择右上角的“设置”按钮,如下图: 之后出现以下界面: 将上图中“插孔设置”选项的AC97前面板勾选上,后面那个HD音频面板不勾选,点击确定。 最后: 成功后可以看到如下截图: 希望帮你解决了问题,记得赞哈,全亲手码字不容易,不过能帮助你解决问题我很开心!哈哈。。。。。。。。

【noip2013普及】 小朋友的数字

题目 有 n 个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。 作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。 请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对 p 取模后输出。题解 第i位的特征值就是前i个包括i的最大连续子段和,暴力n*n的算法数据明显超时,这里用dp求最大字段和,用sum表示结尾是第i位的最大连续字段和,用max1表示第i位之前的最大连续字段和,用max2表示第i个人的分数 初始化代码: cin>>a[1]; max2=a[1]+a[1]; sum=a[1]; max1=max(sum,0); sum=max1; bool flag=true; 循环代码: for(i=2;i<=n-1;i++) { scanf("%I64d",a[i]);//注1 sum+=a[i]; max1=max(sum,max1); sum=max(0,sum); max2=max2+max1; if(!flag) max2=mod(max2,p);//注2 if(max2>a[1]) flag=false; } 取模代码: long long mod(long long aa,long long bb) { if(a<0) {return -((long long)abs(aa))%bb;} else return aa%bb; } 注1:这里用cin会超时;并且输入输出long long 型时一定要注意::linux下用“%lld”;windows下用“%I64d”!!! 注2:这题答案有可能会很大,需要在加的过程中取模,并且取模要自己写,因为负数取模不靠谱;

iOS 中各种折线.曲线.图形绘制方法集锦(折线图.走势图.柱状图.动态曲线图.形状图.划线图)

前言 具体实现如下: 目录 前言 第一 折线图实现 .1) 自定义视图实现 .2)关键技术实现 .3) 方法调用 .4) 效果展示 第二 走势曲线图实现 .1) 导入DJChart第三方库 .2)横竖轴参数设置 .3) 方法调用 .4) 效果展示 第三 画线图实现 .1) 导入ZXQuartz第三方库 .2) 自定义视图,画各种图形 .3) 方法调用 .4) 效果展示 第四 柱状图实现 .1) 导入ZXQuartz第三方库 .2)横竖轴参数设置 .3) 方法调用 .4) 效果展示 第五 各式图形实现 .1) 导入DJChart第三方库 .2)关键技术实现 .3) 方法调用 .4) 效果展示 第六 饼状图实现 .1) 关键技术实现 .2) 方法调用 .3) 效果展示 总结 前言 大家经常在做项目过程中,都会遇到一些画图,例如我们在天气预报中,统计这一周的天气状况变化时,这时我们就需要用折线图来进行统计(图一);例如统计就业率时,我们可能会用到柱状图等等. 首先我们来看看这样的折线该怎么实现呢?.现在我们来看看整体效果图. 现在我们来看看各种不同的图形到底是什么样的. 1) 折线图 2) 走势趋势图 3) 画线图 4) 柱状图 5) 各种图形 6)饼状图 好了看了上面各种折线图,大家一定很关心这些折线图是如何完成绘制的,下面我们就来看看各种图形的具体实现.

python的面向对象基础

python的面向对象基础 1.类和对象基础 类具有抽象性、封装性和多态性。 类的抽象性:类是对具有共同方法和属性的一类对象的描述。类的封装性:类将属性和方法封装,外部都是不可见的,只有通过类提供的接口才能与属于类的实例对象进行信息交换。类的继承性:类可以从已有的类派生。派生出的类具有父类的方法和属性。类的多态性:类可以根据不同的参数类型调用不同的方法。同一个方法可以处理不同类型的参数。实际上,python的内部已实现了多态,在python中,使用类不需要考虑太多不同类型之间数据的处理问题。 2.python中类使用 2.1属性和方法 类的属性=类内部的变量 类的方法=类内部定义的函数 类内部的属性若以双下划线开始,则其为类的私有属性,不能在类的外部被使用或者访问。 在类内部使用def可以为类定义一个方法,与函数定义不同的是,类的方法必须包含参数self,且self必须为第一参数。 同理,类内部的方法若以双下划线开始,则其为类的私有方法。 class Book: #定义Book类 __author = '' #定义Book类的私有属性 __name = '' __page = '' __press = '' price = 0 #定义Book类的公有属性 def show(self): print(self.__author) print(self.__name) def set(self, author, name): #定义公有方法(设置其私有属性__name和__author) self.__name = name self.__author = author def __check(self, item): #定义私有方法 if item == '': return 0 else: return 1 b = Book() #生成类的实例b b.set('Tom', 'Py Class Demo') #调用公有方法set,向其传递参数 b.show() #调用公有方法show,输出 a = Book() #生成类的实例a a.

指针

观察上面的程序和输出,怎么去理解呢,就是change1它是在栈区又开了一个临时变量来接受传进来的参数,也就是a,所以change1中的指针和传进来的参数的指针不是一个,由此证明它们不是一个变量。所以你在change1当中做的改变随着函数结束就消失了~并没有造成什么影响。但是对于change2,他传入的是一个参数的指针,是确实把指针指向的内容给修改了,所以函数结束后,a的值被改变了。这个要好好理解一下。

Expression is not assignable

不知道有没有跟我遇到同样的错误,今天研究一下为什么。 self.view.frame.size.width = 20; 当我们这样去写上面的语句的时候会报错Expression is not assignable。为什么会这样,起始还是对OC理解的不够透彻,分析一下他的语句, self.view是利用点语法调用view的getter 方法,然后view调用frame的getter方法,也就是这种形式 [[self view] frame] 但是到了frame这之后,就不能再这么调用了,因为frame是一个结构体,而之前通过点语法获取到的是函数返回值,所以你不能再将一个值赋值给函数返回值。 就是这样,你需要通过一个临时变量,像这样 CGRect tmpFrame = CGRectMake(0, 0, 20, 10); self.view.frame = tmpFrame; CGSize tmpSize = CGSizeMake(20, 20); CGRect frame; frame.size = tmpSize; self.view.frame = frame;

UI组件——GridLayout

2019独角兽企业重金招聘Python工程师标准>>> 1 GridLayout(网格布局) 在Android4.0开始引入。 GridLayout可以把布局分为几行和几列。 GridLayout可以设置一个组件横框多少行,纵夸多少列。 GridLayout和TableLayout很相似,但是如果要设计行列布局,GridLayout使用更方便、更高效。因为: GridLayout works with a flat-view hierarchy, where child views set their locations in the grid by specifying the rows and columns they should be in. By maintaining a flat hierarchy, GridLayout is able to more swiftly layout its child views. The new GridLayout control for Android 4.0 is very powerful and we've just scratched the surface of what it can do 2 GridLayout常见属性 GridLayout常用的XML属性和方法说明 XML属性 相关方法 说明 android:alignmentMode setAlignmentMode(int) 设置该布局管理器采用的对齐模式 android:rowCount setRowCount(int) 设置该网格的行数 android:columnCount setColumnCount(int) 设置该网格的列数量 android:rowOrderPreserved

Linux系统的内存、硬盘、CPU等信息检查

今天需要检查服务器的硬件情况,所以查了一下命令。 (转载:http://blog.csdn.net/xb12369/article/details/40822389) # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看计算机名 # lspci -tv # 列出所有PCI设备 # lsusb -tv # 列出所有USB设备 # lsmod # 列出加载的内核模块 # env # 查看环境变量资源 # free -m # 查看内存使用量和交换区使用量 # df -h # 查看各分区使用情况 # du -sh # 查看指定目录的大小 # grep MemTotal /proc/meminfo # 查看内存总量 # grep MemFree /proc/meminfo # 查看空闲内存量 # uptime # 查看系统运行时间、用户数、负载 # cat /proc/loadavg # 查看系统负载磁盘和分区 # mount | column -t # 查看挂接的分区状态 # fdisk -l # 查看所有分区 # swapon -s # 查看所有交换分区 # hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备) # dmesg | grep IDE # 查看启动时IDE设备检测状况网络 # ifconfig # 查看所有网络接口的属性 # iptables -L # 查看防火墙设置 # route -n # 查看路由表 # netstat -lntp # 查看所有监听端口 # netstat -antp # 查看所有已经建立的连接 # netstat -s # 查看网络统计信息进程 # ps -ef # 查看所有进程 # top # 实时显示进程状态用户 # w # 查看活动用户 # id # 查看指定用户信息 # last # 查看用户登录日志 # cut -d: -f1 /etc/passwd # 查看系统所有用户 # cut -d: -f1 /etc/group # 查看系统所有组 # crontab -l # 查看当前用户的计划任务服务 # chkconfig –list # 列出所有系统服务 # chkconfig –list | grep on # 列出所有启动的系统服务程序 # rpm -qa # 查看所有安装的软件包 cat /proc/cpuinfo :查看CPU相关参数 cat /proc/partitions :查看硬盘和分区 cat /proc/meminfo :查看内存信息 cat /proc/version :查看版本,类似uname -r cat /proc/ioports :查看设备io端口 cat /proc/interrupts :查看中断 cat /proc/pci :查看pci设备的信息 cat /proc/swaps :查看所有swap分区的信息 #unzip test.

NOIP2008普及组传球游戏(动态规划)——yhx

题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师在此吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目。 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球方法被视作不同的方 法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有三个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方 式有1->2->3->1和1->3->2->1,共2种。 输入输出格式 输入格式: 输入文件ball.in共一行,有两个用空格隔开的整数n,m(3<=n<=30,1<=m<=30)。 输出格式: 输出文件ball.out共一行,有一个整数,表示符合题意的方法数。 1 #include<cstdio> 2 int dp[35][35]; 3 int main() 4 { 5 int i,j,k,m,n; 6 scanf("%d%d",&n,&m); 7 dp[0][1]=1; 8 for (i=1;i<=m;i++) 9 { 10 dp[i][1]=dp[i-1][2]+dp[i-1][n]; 11 dp[i][n]=dp[i-1][1]+dp[i-1][n-1]; 12 for (j=2;j<n;j++) 13 dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1]; 14 } 15 printf("%d\n",dp[m][1]); 16 } 动态规划,现在在i号点,上一时刻一定在i+1或i-1。 特殊处理首尾。 转载于:https://www.cnblogs.com/AwesomeOrion/p/5399241.html

<video id="player" src="AusPlayChineseGirl.m3u8" controls="controls" width="90%">your explorer not s

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> AusPlayChineseGirl.m3u8 </title> <meta charset="UTF-8"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> </head> <body> <br> <center> <video id="player" src="AusPlayChineseGirl.m3u8" controls="controls" width="90%">your explorer not support html5 well!</video><br> <script type="text/javascript"> function setPlayerSrc(video_src) { var video=document.getElementById("player"); //var video = document.getElementsByTagName('video')[0]; video.src=video_src; video.play(); } </script> <br><br><br> <a href="#" onClick="javascript:setPlayerSrc('AusPlayChineseGirl.m3u8')">1. AusPlayChineseGirl</a><br><br><br><br> <a href="#" onClick="javascript:setPlayerSrc('HotDance_Tara_Sketch.m3u8')">2. HotDance_Tara_Sketch</a><br><br><br><br> <a href="#" onClick="javascript:setPlayerSrc('Sketch_ZhanShiWuTai.m3u8')">3. Sketch_ZhanShiWuTai</a><br><br><br><br> <a href="#" onClick="javascript:setPlayerSrc('tahiti_Sexy.m3u8')">4. tahiti_Sexy</a><br><br><br><br> <a href="

基于VS2010的MFC串口开发

近日,项目上需要一个上位机软件来监控串口,同时进行一些信息处理和显示。笔者之前接触过VS的开发,于是边搜索边做,最终完成了项目需求。 下面对开发过程中遇到的问题和关键步骤进行总结。 在整个项目开发过程中参考了如下博文: http://wenku.baidu.com/link?url=SXkEsiMcpfqhM3IdT5ZZ97aNTmwfO_74dvJoNSWoCp2FIyudzpd1uBSgh2ccFJS6v0bfUaBNeTk--W9W3b9YWt7FloiHeLD6iGHHFewuA8u 1. 串口中断控制 m_mscom.put_CommPort((m_comb1.GetCurSel()+1)); //选择串口 m_mscom.put_InputMode(1); //设置输入方式为二进制方式 m_mscom.put_Settings(str1); //波特率为(波特率组Á合框)无校验,8数据位,1个停止位 m_mscom.put_InputLen(1024); //设置当前接收区数据长度为1024 m_mscom.put_RThreshold(1); //缓冲区一个字符引发事件 m_mscom.put_RTSEnable(1); //设置RT允许 m_mscom.put_PortOpen(true); //打开串口 如上,在我的项目中要求是接收6个字符引发中断,故将代码中数字改为6,即: m_mscom.put_RThreshold(6); //缓冲区6个字符引发事件 2. 更改初始焦点 在项目开发过程中发现项目运行后,只要按回车键,就会退出。 这个是因为虽然删除了最开始的那个OK确定按键,但是默认初始焦点还是在它上面,故回车键会引发它的事件处理函数,即退出程序。 这里我的处理方法是,在MFC控件界面,ctrl+D,然后界面会变成如下所示: 然后,依次点击你想要的焦点顺序。这样再次运行之后,默认的焦点在1上,按tab键可以切换焦点位置。 3. 控件背景色 项目中需要更改控件背景色,执行步骤如下: 首先,在控件界面,右键-->类向导 然后,依次选择,消息-->WM_CTLCOLOR-->添加处理程序 然后在增加的代码里写下如下语句: HBRUSH C嵌入式物联网系统上位机软件Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); pDC->SetBkMode(TRANSPARENT); HBRUSH B = CreateSolidBrush(RGB(255,0,0)); // TODO: 在此更改 DC 的任何特性 switch (pWnd->GetDlgCtrlID()) { case IDC_EDIT_Sta1: B = CreateSolidBrush(RGB(255,255,0)); …… default: return CDialog::OnCtlColor(pDC,pWnd, nCtlColor); }

MTK Nucleus平台软件log抓取方法

 [DESCRIPTION] MTK 以Nucleus Plus OS为kernel的产品,包括feature phone(6260,6261),M2M(6261),Wearable(2501,2502),软件在开机过程经历了bootrom,bootloader,Nucleus kernel init,kernel schedule这些阶段,每个阶段抓取log的方式也不一样,如有需要某个阶段的log,请按以下说明抓取,如若在使用catcher进行抓取log时候也遇到死机,建议将dump一并抓取分析。 [SOLUTION] 1、brom log和bootloader log抓取方法一致: 只能使用uart连接PC,使用Putty或者超级终端等串口工具,设定好对应com口,波特率为115200.如若抓取的log里面有 bye bye bootloader,说明bootloader已经顺利走完。 2、Nucleus Kernel init log: 工程makefile中将 KAL_RECORD_BOOTUP_LOG 设为TRUE,make new 只能使用uart连接PC,使用catcher连接抓取,波特率设置为921600. 3、Kernel scheduler后: 只能使用Catcher进行抓取log 这个阶段的log可以自行设置为uart(包括波特率)或者usb,TST-PS config和TST-L1 config设定要一致,并与PS config不一致,如若设置为uart,建议波特率设置为921600,太慢会丢更多的log,设置方法有3种如下: 1)拨号*#3646633#进入工模,Device->Set Uart->Uart Setting 2)连接meta设定NVRAM,Other LID->NVRAM_EF_PORT_SETTING_LID->1 可将tst_port_ps和tst_port_l1设置为0, 1, 4, 5,分别代表UART1,UART2,USB1,USB2 tst_baudrate_ps和tst_baudrate_l1设定为921600。 此时port_ps就不能设置与上述设定一致,如若关闭可设为99 3)以上两种设定都是将修改值保存在nvram中,如若有格式化fs区域,设定就会失效,可以修改代码,使用默认配置,这一般使用在遇到开机死机无法进行上述的操作时候采用,并且格式化后依然有效。 在custom\common\hal\nvram\nvram_data_items.c定位到NVRAM_EF_PORT_SETTING_DEFAULT结构,修改成员tst_port_ps、tst_baudrate_ps、tst_port_l1、tst_baudrate_l1,如若ps_port设定有一致,也请修改 这个结构的原形定义在:interface\hal\peripheral\dcl_uart.h typedef struct { kal_uint16 tst_port_ps; kal_uint16 ps_port; UART_baudrate tst_baudrate_ps; UART_baudrate ps_baudrate; kal_bool High_Speed_SIM_Enabled; kal_uint8 swdbg; kal_uint8 uart_power_setting; /* For DCM, Start [Set UART POWER], CTI */ kal_uint8 cti_uart_port; UART_baudrate cti_baudrate; kal_uint8 tst_port_l1; UART_baudrate tst_baudrate_l1; kal_uint8 tst_output_mode; kal_uint8 usb_logging_mode; kal_uint16 tst_port_dsp; UART_baudrate tst_baud_rate_dsp; kal_uint8 usb_cdrom_config; } port_setting_struct; 这里面好多宏控制着好几个分支,不清楚自己的工程是在哪个分支,可以对文件做一个备份,然后把每一个分支都改成一样, 修改后执行编译命令,make remake_dep custom\common\hal\nvram\nvram_data_items.

给radio添加点击事件

1.单独给每个radio添加点击事件 <fieldset id="form-gra-time"> <legend>请选择日期粒度:</legend> <label>日 <input name="gra-time" value="day" type="radio" checked="checked"> </label> <label>周 <input name="gra-time" value="week" type="radio"> </label> <label>月 <input name="gra-time" value="month" type="radio"> </label> </fieldset> var radio=document.getElementsByName("gra-time"); for(var i=0;i<radio.length;i++){ if(radio[i].checked){ radio[i].addEventListener("click",clickFunction); } } 判断选中的radio的值,使用radio[i].value; 给每个radio绑定事件是不推荐的。 2.委托事件 var form_gra_time=document.getElementById("form-gra-time"); form_gra_time.addEventListener("click",function(e){ if(e.target.name=="gra-time"){ graTimeChange(); } }) /*这里判断目标直接使用了target,如果需要跨浏览器的话可以写成var target=e.target||e.srcElement。同样的addEventListener也是不能直接用的 function addEventHandler(ele, event, hanlder) { if (ele.addEventListener) { ele.addEventListener(event, hanlder, false); } else if (ele.attachEvent) { ele.attachEvent("on"+event, hanlder); } else { ele["on" + event] = hanlder;

单缓冲与双缓冲的区别

单缓冲,实际上就是将所有的绘图指令在窗口上执行,就是直接在窗口上绘图,这样的绘图效率是比较慢的,如果使用单缓冲,而电脑比较慢,你回到屏幕的闪烁。 双缓冲,实际上的绘图指令是在一个缓冲区完成,这里的绘图非常的快,在绘图指令完成之后,再通过交换指令把完成的图形立即显示在屏幕上,这就避免了出现绘图的不完整,同时效率很高。 一般用OpenGL绘图都是用双缓冲,单缓冲一般只用于显示单独的一副非动态的图像 http://thatax.blog.163.com/blog/static/20892680200871242445116/ OpenGL的消隐与双缓冲 2008-08-12 16:24:45| 分类: OpenGL | 标签: |字号大中小 订阅 首先是大家可能已经发现,在我们之前提到的所有例子中,在图形的旋转过程中整个图形都有一定程度的闪烁现象,显得图形的过渡极不平滑,这当然不是我们所要的效果,幸好opengl 支 持一个称为双缓存的技术,可以有效的帮助我们解决这个问题。我们知道在我们电脑中,屏幕中显示的东西都会被放在一个称为显示缓存的地方,在通常情况下我们 只有一个这样的缓冲区,也就是单缓冲,在单缓冲中任何绘图的过程都会被显示在屏幕中,这也就是我们为什么会看到闪烁,而所谓双缓冲就是再这个显示的缓冲区 之外 再建立一个不显示的缓冲区,我们所有的绘图都将在这个不显示的缓冲区中进行,只有当一帧都绘制完了之后才会被拷贝到真正的现实缓冲区显示出来,这样中间过程对于最终用户就是不可见的了,那即使是速度比较慢也只会出现停顿而不会有闪烁的现象出现。 在OpenGL 中我们可以通过glut 库中的函数 void glutSwapBuffers(void) 来实现从非显示缓冲区到显示缓冲区的复制 当然在使用双缓冲之前我们也要在 glutInitDisplayMode 设定参数的时候选择GLUT_DOUBLE 而不是之前我们用的 GLUT_SINGLE 相信这两个参数的意思也应该很明白了 在解决了闪烁的问题之后 我们来解决另一个问题 首先我们在窗口中画两个交叉的分别位于ZOX 和 ZOY 平面的长方形 并用不同的颜色填充它们,然后让它们旋转很快我们发现有个比较严重的问题发生了,因为我们发现opengl显然没有空间的位置观念因为它根本不能分辨物体的前后关系,当然也不能做出适当的显示,在opengl中我们使用深度缓冲区来解决这个问题,在这个缓冲区中存放着每个象素深度信息,当有一个新的象素需要显示的时候,我们可以通过一个被称为深度测试的函数来确定它们的先后关系,要使用深度缓冲区有以下几个步骤: 1. 在函数 glutInitDisplayMode(mode) 中将GLUT_DEPTH置位 表明要使用深度缓冲区 2. 使用函数glEnable(GL_DEPTH_TEST) 打开深度测试函数 void glEnable(GLenum cap); void glDisable(GLenum cap); 这两个函数属于基本状态管理函数 用来打开和关闭一些常用的功能,常用的参数有以下几个 GL_BLEND GL_DEPTH_TEST GL_FOG GL_LINE_STIPPLE GL_LIGHTING 3. 是用函数glDepthFunc()来设置深度测试函数 void glDepthFunc(GLenum func) 这里我们比较常用的深度测试函数有 GL_LESS 和 GL_LEQUAL 两者的区别在于当深度相同时是显示新的象素 还是老的象素

B和B+树

B树只适用于:随机检索,不适用于顺序检索; 而B+树把所有关键码都存在叶结点上,这就为顺序检索也提供了方便。 ①B树和B+树用于组织文件的动态索引结构。 ②B树和B+树都是平衡的多分支树。 ③ B树只适用于随机检索,不适用于顺序检索, 而B+树适用于顺序检索和随机检索 B树和B+树都能有效的支持随机检索

JAVA与C当中基本数据类型和基本运算符的区别

JAVA当中的数据类型 大部分跟C都一样 ,都是相通的。不过JAVA当中有一个String类型的,这个就相当于字符串了,比起C当中要用字符型数组来实现字符串要方便很多。 boolean类型的跟C也差不太多,没有太大的区别。 在运算符当中,运算符的优先级和符号就本都是一样的,不过逻辑运算符的表示方法有一点儿的区别。区别感觉也不是很大。 学的时间也不久,就觉得输入输出流和C有点儿区别,还是稍微不太适应的,而且建立文件的方法也不是很容易理解。现在也只是照猫画虎,一步一步的走着。

浅析ADO.NET五大对象

引言 在数据库应用系统中,必定要涉及到对数据库的访问和操作,而ADO.NET则是微软在.NET Framework中负责数据访问的类的库集,那么理清ADO.NET中的五大对象对于我们理解ADO.NET无疑会有很大的帮助。 本文将对ADO.NET做简单的介绍,分析五大对象Connection、Command、DataReader、DataAdapter、DataSet,以及他们之间的关系。 发展 早在1997年时,微软已经开发了许多的数据访问方式,例如DAO(Data Access Object)对象、可以跨越网络访问数据的RDO(Remote Data Objects)以及让DAO组件可以访问ODBC数据源的ODBCDirect技术等等。 如此多的技术,为了减少企业与开发人员在选择、学习与应用上产生的困难,同时适逢COM与OLE的发展,微软将数据访问的核心开始改写为以COM为主的OLE DB,并且在它上面创建一个新的数据访问模型ADO(ActiveX Data Objects)。 然而ADO本身的架构仍然有缺陷(尤其是在开发网络应用程序时,最好的例子就是Recordset无法脱机)。于是在1998年时,微软提出了一个下一代的应用程序开发框架(Application Framework)的项目,其中就包括Storage+,而ADO+就是Storage+的一支。 2000年的时候,微软的Microsoft .NET项目开始成形,许多的微软产品都冠上.NET的标签,ADO+也不例外,改名为ADO.NET,并包装到.NET Framework类库中,成为.NET平台中唯一的数据访问组件。 分析 一图胜过千言万语,在对五个对象详细介绍之前,先用一张图来说明它们之间的关系: Connection 建立与特定数据源的连接。 所有 Connection 对象的基类均为 DbConnection 类,是所有数据库操作的基础,在对数据库操作之前要先建立数据连接。 实例说明(仅以SqlConnection为例): string connectionString = "";//连接字符串 SqlConnection connection = new SqlConnection(connectionString)//初始化 SqlConnection 类的新实例 connection.Open();//打开数据库连接 connection.Close();//关闭连接 使用connection连接的时候记得打开、关闭,建议使用using,确保连接始终关闭,这样可确保在代码退出代码块时自动关闭连接。 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // } Command 对象定义了将对数据源执行的指定命令。 表示要对数据库执行的一个 Transact-SQL 语句或存储过程。所有 Command 对象的基类均为 DbCommand 类。 DataReader 从数据源中读取只进且只读的数据流。 所有 DataReader 对象的基类均为 DbDataReader 类,DataReader对象只允许以只读、顺向的方式查看其中所存储的数据,提供一个非常有效率的数据查看模式,同时DataReader对象还是一种非常节省资源的数据对象。

命令行svn commit时注释实现换行

svn ci -m "11111" 其中,111111 就是你填写的注释。 如果你想换行写,也是可以的,只要你不写后面的那个引号,你可以写一行就回车一次,最后写完了,再加上后面的引号,然后再回车,就执行提交动作了。 svn ci -m "11111 >22222 >33333"

微博主页面布局思路

微博主页面布局思路,以及方法的提取思路: public class MainActivity extends FragmentActivity implements OnCheckedChangeListener, OnClickListener { private RadioGroup rg_tab; private ImageView iv_add; private FragmentController controller; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); controller = FragmentController.getInstance(this, R.id.fl_content); controller.showFragment(0); initView(); } private void initView() { rg_tab = (RadioGroup) findViewById(R.id.rg_tab); iv_add = (ImageView) findViewById(R.id.iv_add); rg_tab.setOnCheckedChangeListener(this); iv_add.setOnClickListener(this); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_home: controller.showFragment(0); break; case R.id.rb_meassage: controller.showFragment(1); break;

Yahoo! Cloud Serving Benchmark (YCSB)

News YCSB 0.7.0 (release note) is now available for download. Give it a try! https://github.com/brianfrankcooper/YCSB/releases/download/0.7.0/ycsb-0.7.0.tar.gz Links ycsb-users@yahoogroups.com http://groups.yahoo.com/group/ycsb-users Papers and Presentations Source code: http://github.com/brianfrankcooper/YCSB/ Welcome Michi Mutsuzaki (m1ch1) as a new maintainer ofYCSB! Overview There are many new serving databases available, including: HBaseHypertableCassandraCouchbaseVoldemortMongoDBOrientDBInfinispanRedisGemFireDynamoDBTarantoolMemcached …and many others It is difficult to decide which system is right for your application, partially because the features differ between systems, and partially because there is not an easy way to compare the performance of one system versus another.

android studio运行程序找不到class,java.lang.ClassNotFoundException: Didn't find class,完美解决!

在开发中是不是会遇到 java.lang.ClassNotFoundException: Didn't find class "*****Activity" on path: /data/app/*******.apk这样的错误,反正我被他折磨的够狠,网上的方法各种试都不行,最后偶然得知尝试了以下者中方法,解决方法: 将箭头的地方,要把版本都降低一下,开始我的23.0.3改成23.0.2和v7包引用也要降低,然后clean 最终完美解决!

Quickstart Docker Engine(快速了解Dockers引擎)

本文章假设你已经安装了docker服务,如果你已经安装了docker服务,可以通过下面的命令进行验证。 # Check that you have a working install $ docker info 如果获得该提示 1.docker: command not found 或者2./var/lib/docker/repositories: permission denied 1.你可能没有安装docker服务 2.你可能权限不够,不能执行该命令,你可以sudo命令前缀,也可以建立一个用户组,该组用户拥有执行docker命令的权限,省去每次敲sudo命令 下载一个docker镜像 # Download an ubuntu image $ docker pull ubuntu 该命令会从从DockerHub中下载一个 ubuntu 镜像 运行一个交互式的shell 我们从镜像中创建容器,并在容器下运行一个交互式的shell $ docker run -i -t ubuntu /bin/bash -i :interactive 的缩写,表示启动一个交互式的容器. -t :Teletype的缩写,创建一个虚拟的交互式输入输出接口,通俗就是 stdin 与 stdout. 如果希望跳出tty,回到原来的shell中,可以按 Ctrl-p + Ctrl-q. 绑定Dockers一个 host/port 或者Unix socket 通过 -H 参数,我们能运行一个Docker后台服务监听IP地址和端口,默认情况下,Docke监听unix:///var/run/docker.sock ,仅仅允许root用户. 不过你可以设置 0.0.0.0:2375 或者一个网段去赋予其他用户访问docker的权限, 同样的,Docker客户端也可以使用 -H 去连接unix:///var/run/docker.

Amazon CTO:我在打造AWS的10年里学到的10条经验

Amazon CTO:我在打造AWS的10年里学到的10条经验(转) Amazon 的 CEO Jeff Bezos 前几天在致股东的信中表示 ,亚马逊云服务 AWS 目前已经有超过 100 万的用户,2016年 的营收也将突破 100 亿美元。Amazon 的 AWS 服务是在 2006年3月 推出,距今已有整整 10年 的时间了。AWS 最早推出的云服务是简单储存服务 Simple Storage Service (S3),后来又陆续推出了 Amazon 弹性计算网云 Elastic Compute Cloud (EC2)、亚马逊简单数据库(Amazon SimpleDB)、亚马逊简单队列服务(Amazon Simple Queue Service)以及 Amazon CloudFront 等云服务。目前,成千上万的创业公司在 AWS 的数据中心和服务基础上构建了自己的在线业务。不仅大量小公司依赖于 Amazon AWS 的云计算服务,很多诸如 Adobe、GE、Netflix 和 Pinterest 这样的大公司也都在使用 Amazon 的 AWS 服务。 在 Amazon 的 AWS 服务上线 10 周年之际,推动 AWS 服务发展的核心人物、Amazon 的 CTO Werner Vogels 在本文中专门总结和分享了他在 AWS 上线运营 10年 过程中的学到的 10 条经验,希望对大家有所启发和借鉴。

线性规划单纯形模板

#include<bits/stdc++.h> using namespace std; const int Maxn=110,Maxm=59; class Simplex{ /* 功能: 接受有n个约束,m个基本变量的方程组a[0~n][0~m] a[0][]存放需要最大化的目标函数,a[][0]存放常数 Base[]存放基本变量的id,初始为1~m Rest[]存放松弛变量的id,初始为m+1~m+n 返回此线性规划的最小值ans 要求方案的话,Base[]中的变量值为0,Rest[]中的变量值为相应行的[0] 如果solve 返回1,说明运行正常ans是它的最大值 返回0,说明无可行解 返回-1,说明解没有最大值 测试: m=2,n=3 double a[4][3]={ {0,1,3}, {8,-1,1}, {-3,1,1}, {2,1,-4} }; solve=1,ans=64/3; 注意ac不了可能是eps的问题 */ public: static const double Inf; static const double eps; int n,m; double a[Maxn][Maxm]; int Base[Maxm],Rest[Maxn]; double val[Maxm]; double ans; void pt(){ for(int i=0;i<=n;i++){ for(int j=0;j<=m;j++)printf("%.2f ",a[i][j]); puts(""); } } void pivot(int x,int y){//将第x个非基本变量和第y个基本变量调换 swap(Rest[x],Base[y]); double tmp=-1./a[x][y]; a[x][y]=-1.

emWin界面库注意事项之自定义回调函数之后,句柄为0

由于在嵌入式设备上可供使用的界面库很少,项目当中所使用的界面库为德国SEGGER公司开发的emWin界面库。使用上和windows的GDI大致类似,也提供了丰富的API接口。如果我们需要对控件进行自绘的话,一定要进行的一个操作是通过设置回调函数,获取控件的消息循环,进行自定义处理。回调函数的命名一般为_cb函数名的方式。 通过设置了回调之后,我即可以在控件内部进行自绘了,但是如果我们想要重新获得控件的句柄时,就会发现无法利用控件的API进行操作了。原因是为什么呢? 这是因为在设置了自定义的用户回调函数之后,重新调用WM_GetDialogItem函数获得的句柄时0,所以你无法进行操作。 唯一的解决方法是,在设置回调函数之前,即对句柄进行赋值,而后对句柄进行操作即可。

linux文件系统之Inode

文件名 -> inode -> device block 转自: http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html 一、inode是什么? 理解inode,要从文件储存说起。 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。 文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。 二、inode的内容 inode包含文件的元信息,具体来说有以下内容: * 文件的字节数 * 文件拥有者的User ID * 文件的Group ID * 文件的读、写、执行权限 * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。 * 链接数,即有多少文件名指向这个inode * 文件数据block的位置 可以用stat命令,查看某个文件的inode信息: stat example.txt 总之,除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。 三、inode的大小 inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。 每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。 查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。 df -i 查看每个inode节点的大小,可以用如下命令: sudo dumpe2fs -h /dev/hda | grep "Inode size" 由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。 四、inode号码 每个inode都有一个号码,操作系统用inode号码来识别不同的文件。 这里值得重复一遍,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。 使用ls -i命令,可以看到文件名对应的inode号码: ls -i example.txt 五、目录文件 Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。 目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。 ls命令只列出目录文件中的所有文件名: ls /etc ls -i命令列出整个目录文件,即文件名和inode号码: ls -i /etc 如果要查看文件的详细信息,就必须根据inode号码,访问inode节点,读取信息。ls -l命令列出文件的详细信息。 ls -l /etc 六、硬链接 一般情况下,文件名和inode号码是"

Fedora 安装chrome浏览器的方法<>

Fedora 安装chrome浏览器的方法 www.111cn.net 编辑:netuser 来源:转载 下面本文章从安装chrome浏览器的实现方法到安装过程中碰到问题的解决方法,希望此例子对各位在Fedora安装chrome会有帮助哦。 在google网站下载chrome速度很慢,但是添加了chrome的源之后,就可以在终端通过yum install 来安装chrome了,会快很多。 首先在 /etc/yum.repos.d 里建立一个名为 google.repo 文件,然后复制以下代码到其中,然后保存: 32位系统: 代码如下复制代码 [google] name=Google – i386 baseurl=http://dl.google.com/linux/rpm/stable/i386 enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub 64位系统: 代码如下复制代码 [google64] name=Google – x86_64 baseurl=http://dl.google.com/linux/rpm/stable/x86_64 enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub 然后使用(需管理员权限): 代码如下复制代码 yum install google-chrome-stable --nogpg 来安装最新稳定版 yum install google-chrome-unstable --nogpg 最新版chrome 这样就可以安装了! 文章后面补充在安装过程碰到的问题解决方法 可能会出现的问题(可能性很大): 出现如下错误: warning: google-chrome-stable_current_i386.rpm: Header V4 DSA/SHA1 Signature, key ID 7fac5991: NOKEY error: Failed dependencies: lsb >= 4.0 is needed by google-chrome-stable-18.

[swift实战入门]手把手教你编写2048(一)

苹果设备越来越普及,拿着个手机就想捣鼓点啥,于是乎就有了这个系列,会一步一步教大家学习swift编程,学会自己做一个自己的app,github地址:https://github.com/scarlettbai/2048.git。 这篇文章需要大家了解一些swift基本语法,这里注重实践,就不讲太多基本语法了,不懂的大家可以Google一下,swift开发环境也很简单,直接在mac上安装一个XCode即可,首先我们来看下最终我们要实现的效果: 当然你也可以将其中的数字换成文字给你女票安手机上,还可以给个小惊喜,效果如下: 从上图可以看出来,最终效果其实主要分为计分板和游戏面板,游戏面板里是一个背景和很多的小块,小块中间有间隔,今天先教大家编写出游戏面板。 首先新建一个swift工程,这里就不多说了,然后新建文件NumbertailGameController.swift,这个文件主要处理游戏的初始化等逻辑 新建一个NumbertailGameController类继承UIViewController,其中包含如下属性: class NumbertailGameController : UIViewController { var demension : Int //2048游戏中每行每列含有多少个块 var threshold : Int //最高分数,判断输赢时使用,今天暂时不会用到,预留 let boardWidth: CGFloat = 260.0 //游戏区域的长度和高度 let thinPadding: CGFloat = 3.0 //游戏区里面小块间的间距 let viewPadding: CGFloat = 10.0 //计分板和游戏区块的间距 let verticalViewOffset: CGFloat = 0.0 //一个初始化属性,后面会有地方用到 } 接下来给NumbertailGameController添加init方法 init(demension d : Int , threshold t : Int) { demension = d < 2 ? 2 : d threshold = t < 8 ?

PointPlay(document.getElementById('selectForPlay').value);

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> New Document </title> <meta charset="UTF-8"> <style type="text/css"> <!-- body { margin-left: 1px; margin-top: 1px; } .style1 {color: #FA5D94} .style8 {color: #0058DD} .style2 {color: #FE000B} .style9 {color: #666666} .STYLE11 {font-size: 12px} body,td,th { font-size: 12px; } --> </style> <!-- script type="text/javascript" src="jquery-1.11.1.min.js" / --> <script Language="JavaScript" > setInterval(show1,5000);//5s显示一次下载进度 var bstartnextplay = false; function show1() { var pos = CoolPlayer.get_CurTaskProcess()/10; if(pos > 60) { StartNextDownFile(); } var posv = "

GB28181,实时流点播流程解读

这里不对流程过程做叙述,28181文档中的描述已经很详细了。我这里做的,是将整个过程,转换为交谈对话的过程,通过多个第一人称的角度叙述出来每一个步骤的目的。我这样做的目的,是为了能给新学习28181国标的朋友能够更好地理解流程。 我学习的时候,没有人讲解,只是让看代码,确实比较费劲。希望我的分享,能让大家更快入门,更快掌握。 我使用visio将整个过程绘制了出来,下面展示导出来的图片,不提供visio稿件。如有需要,请qq索取。 第一幅图,是国标文档中的图示, 下面的图,是增加了注释和解读。 如果图片看不清楚,可以在下面地址进行下载; 点击链接下载

Shell 脚本等待上一行执行完成再执行下一行的方法

在开发中,我们有时候需要使用 Shell 脚本完成一些简单的操作,但是往往有的操作比较耗时,但是我们又不得不等待它执行完成后才能进行下面的步骤,所以许多朋友往往使用sleep等方法来强制等待操作完成,其实完全没有必要,我们只需要使用一个小小的 tricky 方法就可以实现精准等待操作完成的效果。 Shell 默认提供了获取命令执行输出的方法,即用 ` 号将需要获取输出的操作括起来,并赋值给一个变量,则 Shell 会在等待命令执行完成后把输出内容用于赋值,所以,这就是实现了我们需要的等待效果,并且时间精准性很高。 假设command 1执行需要1s,command 2执行需要视当前资源占用率花费10s~30s不等,command 3执行需要1s,则实现的代码如下: #!/bin/sh command 1 output=`command 2` command 3

git如何删除已经 add 的文件 (如何撤销已放入缓存区文件的修改)

使用 git rm 命令即可,有两种选择, 一种是 git rm --cached "文件路径",不删除物理文件,仅将该文件从缓存中删除; 一种是 git rm --f "文件路径",不仅将该文件从缓存中删除,还会将物理文件删除(不会回收到垃圾桶)。 git --如何撤销已放入缓存区(Index区)的修改 修改或新增的文件通过 git add --all命令全部加入缓存区(index区)之后,使用 git status 查看状态 (git status -s 简单模式查看状态,第一列本地库和缓存区的差异,第二列缓存区和工作目录的差异), 提示使用 git reset HEAD <file> 来取消缓存区的修改。 不添加<file>参数,撤销所有缓存区的修改。 另外可以使用 git rm --cached 文件名 ,可以从缓存区移除文件,使该文件变为未跟踪的状态, 同时下次提交时从本地库中删除。 注: 没有带参数的 git reset 命令,默认执行了 --mixed 参数,即用reset版本库到指定版本,并重置缓存区,在上面的命令中指定的目录版本是HEAD,即当前版本,所以实际上没有任何修改,仅是重置了缓存区。 “无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。”

速判断南北桥IO是否损坏

一、通过测PCI槽、AGP槽对地打阻值可判定南北桥有无损坏 1、PCI槽中所有的AD复合线对地打阻值都为300~800之间数值,说明南桥好;若由无穷大,说明南桥虚焊;若有3根或3根以上导通,说明南桥坏; 2、AGP槽对地所有AD复合线对地打阻值都为300~800之间数值,说明北桥好;若由无穷大,说明北桥虚焊;若有3根或3根以上导通,说明北桥坏; 3、内存槽,通过对数据线进行打阻值判断,都为300~800之间数值,说明北桥好;若由无穷大,说明北桥虚焊;若有3根或3根以上导通,说明北桥坏。 二、对主供电部分输出电感一端或Q1场管的S极、Q2场管的D极打阻值,在不插CPU或假负载的情况下,即判断北桥好坏 1、在40左右数值为正常 2、在20~30左右为北桥有轻微损坏 3、在10以下说明北桥损坏 三、对于IDE口、USB口打阻值来判断南桥是否有损坏 1、IDE口,打2~9针、11~19针、21~29针、37~39针,对地阻值有600左右且相差不大的数值为南桥正常;有无穷大或1000以上的数值为南桥虚焊或IDE口到NQ之间的小电阻烧断;如阻值明显偏小为南桥损坏 2、USB口,打两个USB口的2、3针共4根针的阻值,如有500左右的数值说明南桥正常;如有无穷大说明南桥虚焊或它们到南桥之间的小电阻损坏;如有阻值明显偏小说明南桥损坏 845GL的那不是AGP槽,虽然长的一样,但是那个叫做ADD槽,插ADD卡的,AGP数字显示扩展卡(ADD扩展卡)不是一个独立工作的设备,它必须与Intel Graphics Memory Controller Hub (GMCH)协同工作以提供高质量的数字信号输出。GMCH是CPU中的高度集成化图形处理单元。这样它所提供的多媒体引擎可提供高质量的2D、3D、视频和图形显示功能。它通过1.5v AGP接口提供外部图形处理引擎。当ADD扩展卡接入1.5V AGP接口,可提供数字信号输出功能。 ADD卡包括采用全高板型设计的TMDS/TV ADD card(支援DVI/TV输出),及针对超薄PC采用半高板型设计的TMDS ADD card(DVI输出)。845G/GL芯片组主板可通过这两张子卡直接连接液晶显示器,或是进行TV输出,对于商用机来说这的确是一个相当有吸引力的廉价解决方案。 ADD卡的接口与AGP完全一样,这也是给大家带来了不少的困惑的主要原因。在此,特别说明,采用Intel845G/GE(如:P8、P8/333)的主板上的AGP插槽,可以使用ADD卡,也可以插AGP显卡;但是采用845GL/GV芯片组的主板(如:P8L、P7BL、BA1/GV),只能用ADD卡,否则可能会烧毁主板。 IO要直接判断好坏有些困难.不同的IO引脚定义不同,判断方法也不尽相同我就拿W83627HF为例说一下吧!61# +5Vsb待命电压70# +3.3V待机电压。72# +5V待机电压,触发后为低电平74# ,76# 电池电压输入(+3V)12#, 48#, 77#,97#,114# +5Vcc(核心电压)28# +3.3Vcc(核心电压)以上任何一脚对地短路一般可以判断IO坏.31# -37#打印机管理 58# ,59#,60#,62#,63#,65#,66# 鼠标键盘管理打以上二极体值如果不相等一般可以判断IO坏.以上说的只是一般情况下!况且要打那么多针脚的值很麻烦.要准确判断是否IO坏,只有用替换法了一般如果怀疑IO有问题就直接替换就知道了. 快速判断南桥好坏 一,PCI a14脚对地阻值小于80。 二,南桥周围电容对地短路。 三,USB数据线对地短路。 四,待机时,南桥温度高。 五,COMS跳线中间脚对地短路。 六,1117中间脚对地短路。

Socket编程-1V1聊天

==> 学习汇总(持续更新) ==> 从零搭建后端基础设施系列(一)-- 背景介绍 提供一个1V1聊天的小例子供大家参考.直接贴代码,废话不多说. 注:在VS2015代码测试成功,其它编译器如有问题自行解决. 先来一张效果图: 服务端: #include <WinSock2.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib,"ws2_32.lib") int main() { //存放套接字信息的结构 WSADATA wsaData = { 0 }; SOCKET ServerSocket = INVALID_SOCKET;//服务端套接字 SOCKET ClientSocket = INVALID_SOCKET;//客户端套接字 SOCKADDR_IN ServerAddr = { 0 };//服务端地址 SOCKADDR_IN ClientAddr = { 0 };//客户端地址 int iClientAddrLen = sizeof(ClientAddr); USHORT uPort = 18000;//服务器监听端口 //初始化套接字 if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { printf("WSAStartup failed with error code: %d\n", WSAGetLastError()); return -1; } //判断版本 if (LOBYTE(wsaData.

MFC-线程同步

线程同步有四种方法. 两个简单的线程函数例子: UINT Thread1(LPVOID lParam) { for (int i = 0; i < 10000000;i++) { sum++; } SetDlgItemInt(AfxGetApp()->m_pMainWnd->m_hWnd, IDC_STATIC,sum,TRUE); return 0; } UINT Thread2(LPVOID lParam) { for (int i = 0; i < 10000000; i++) { sum++; } SetDlgItemInt(AfxGetApp()->m_pMainWnd->m_hWnd, IDC_STATIC, sum, TRUE); return 0; } 方法一:使用临界区对象(CCriticalSection类) 1.在构造函数中创建一个临界区对象 g_critical_section = new CCriticalSection(); 2.分别给两个(或多个)线程加锁 for (int i = 0; i < 10000000;i++) { //加锁 g_critical_section->Lock(); sum++; //当操作共享数据时为了防止同时被操作导致结果错误, //所以要加锁,这个时候其它线程就不能对这个加锁的数据进程操作,需要等到这个数据解锁才能进程操作 //解锁 g_critical_section->Unlock(); } 3.

Build2016两场Keynote的干货汇总

Build 2016 直播看的大家心情为之振奋,信仰充值爆棚,如果你不信,那么请仔细看好下面的内容: 在Build 2016 Day 1 Keynote则重点会讲了Windows、人工智能、HoloLens、小娜等…… 最先出场的是CEO纳德拉,他在演讲中强调:“技术改变世界,技术改变我们的生活、学习、交流方式。我们要不断创新,促进人类社会文明的进步”,并且再次提到移动为先,云为先。并且还推出了微软的新一个理念— conversation as aplatform 随后,微软Windows部门执行副总裁TerryMyerson上台,介绍Windows10新特性。要知道Windows10是用户增长最快的Windows系统,它更快更安全,并且适应更多的不同的尺寸设备。同时,TerryMyerson 公布 Windows10已经拥有2.7用户,使用时长更是高达750亿小时。现在已有500种新的Windows10设备,就连新mac也支持Windows10了 。 然后上场的就是Bryan Roper,他谈论到在Windows10年度更新中,Windows Hello技术可以在Edge浏览器中使用,Microsoft Edge也是唯一一款支持生物识别技术的浏览器。内置在Windows10中的Microsoft Edge浏览器将会支持Windows Hello。也就是说,未来你就可以通过Microsoft Edge浏览器在浏览网页时,同样可以通过脸部识别、指纹扫描等形式来进行安全验证登陆。 智能Ink功能不仅是笔,还有尺子。笔记中的信息如日期、地址可以被 Cortana直接识别,而你的手写的内容直接就可以作为Cortana的提示内容。Cortana可以将note中的内容转换到系统提醒功能中,还可以把写好的内容直接发到推特上。 Ink还可以跟地图很方便地集成,将地图智能地识别成路线,同时还有3D效果。Bryan Roper特别演示了基于Windows10和Surface平板的各种酷炫功能。3D地图绘图可以直接2D转换到3D地图上。绘图的辅助工具中各种虚拟直尺,虚拟卷尺,对于绘图的设计师来说非常棒的体验。Ink还可以结合3D地图智能计算路径,然后在视频中Bryan Roper还自带了尺子出来。 Ink不仅仅再是电脑屏幕上简单的轨迹和线条,而是变得能够与应用中的各种逻辑进行交互,Ink变得有生命,让开发人员和用户激发Ink的更多使用场景。 接下来就是重磅信息了,Windows集成Bash Shell,Native bash来到Windows、Native bash来到Windows。是不是听起来很令人兴奋呢? 作为Day1的第一个重头戏,Bash来了,这可不是虚拟机,也不是跨平台兼容执行文件,而是UWP!现在在Windows10中也可以直接执行Linux命令了。 现场演示中跑的是Ubuntu,而且还可以用apt-get。Linux SHELL-Linux命令解释器。Bash只是众多Linux Shell的一种。Bash Shell是sh Shell的增强版本。目前Linux大部分使用的都是Bash Shell。 Hosted Web App在Windows应用环境下可以直接访问文件系统直接调用系统Camera,可以直接调用WinRT API,这也就说明有了更加丰富的底层接口API。 Win32和.NET应用可以使用转化器变成UWP,并直接通过商店发布,还可以访问UWP的所有API。Win32 Appor Game只需要一些非常小的更改就可迁移到Windows RT平台上来。 Win32应用还可以使用动态磁贴,并且可以获得lives tiles和吐司消息(toast message)不需要改动Win32和.NET应用代码,会和Install Shield等打包工具合作直接生成UWP Package。Win32游戏可以方便变为UWP现代化游戏体验。有了Win32转换器让UWP不再促襟见肘。 下面即将出场的是今年刚刚嫁到我软的Xamarin Visual Studio可以实现开发所有平台应用,使用Xamarin开发跨平移应用非常简单,可以调试Android和Windows应用,还可以design iOS应用。点击链接,现在就下载Visual Studio。 VisualStudio下载: http://t.cn/Rw1ZH3v 终于到了大家期待的XBox游戏环节和马上要登场的HoloLens了,游戏一开场就是Windows 10上的Forza。有请 Phil Spencer登场,Phil说,Windows 10将是一个完全开放的游戏生态,对于开发者来讲,也是最好的平台。 就是这项最新推出一项服务”dev mode”,能够让任何人把零售版XBox注册成开发用XBox,通过一个Store应用开启,重启完就变成开发版,可以通过Visual Studio调试应用。以后retail的机器也可以成为开发机,现在UWP可以开始在XBox上部署了。在Visual Studio中使用debug remote device就可以将UWP应用部署在XBox上,Window RT API同样适用于 XBOX,例如:语言识别功能。

求数字特征值(C语言)

对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值。对于一个整数,从个位开始对每一位数字编号,个位是1号,十位是2号,以此类推。这个整数在第n位上的数字记作x,如果x和n的奇偶性相同,则记下一个1,否则记下一个0。按照整数的顺序把对应位的表示奇偶性的0和1都记录下来,就形成了一个二进制数字。比如,对于342315,这个二进制数字就是001101。 代码: #include <stdio.h> #include <math.h> int main() { int n,level=1,byte=1,sum=0,b; scanf("%d",&n); if(n>=0 && n<=100000){ b=n%10; if(b%2) sum=1; while(n/10){ n/=10; b=n%10; level++; if(b%2==level%2){ byte=pow(2,level-1); sum+=byte; } } printf("%d\n",sum); } return 0; }

处理器一条指令需要几个时钟周期?

思考个小问题,处理器执行一条指令需要几个时钟周期。 对于软件工程师来说,印象流我们可能会觉得执行一条指令一个时钟周期嘛,一条指令算是一个最小的原子操作,不可能再细分了吧。 如果看看诸如《see mips run》,《arm体系架构》等书籍就会了解到,这个问题可没这么简单了,因为处理器设计中使用了流水线技术。 一条指令还是相当复杂的,处理器在一个时钟周期内肯定是完不成的,可能需要好多个时钟周期来完成执行。如果这样让处理器执行完一条指令,再去执行另一条,处理器的效率是很低的,假如一条指令是5个时钟周期完成,对于500MHZ的处理器串行运行指令,1秒内取指100000000次。 因此处理器引入了流水线技术,将一条指令划分为多个功能,由不同的功能部件来执行,并且这些功能部件可以并行工作。下面是一个arm7的三级流水线运行图。 流水线划分为取指 译码 执行,但并不是仅需3个时钟周期即执行完指令。因为执行单元模块的操作较多,可能需要多个周期,取指 译码一般是一个时钟周期,这样可以看出虽然一条指令完成需要多个时钟周期,但是总体来说看在每个时钟周期都有一条指令开始取指。如果我们的处理器是500MHZ,则1秒内取指了500000000次。 不同的处理器设计时流水线级数不一样,现在主流的有三级 五级 七级,增加流水线级数,简化流水线的各级逻辑,可以提高处理器的性能。 回答咱们开头的问题也就明白了,一条指令需要的时钟周期还真不固定,这得看处理器的流水线级数,也得看该指令的复杂度,在执行阶段需要几个时钟周期。 对于流水线各级具体工作这里就不细说了,网上文章很多,毕竟咱们是做软件的,硬件点到为止,流水线各级工作是有处理器内部逻辑单元来完成的,对于软件来说都是不可见的,软件可操作的最小原子操作就是指令。 不过呢,处理器的流水线技术在有一个事情对咱们软件造成了影响,那就是PC值。 据我了解的处理器流水线设计,前三级基本都是取指 译码 执行。处理器的PC寄存器中存储的是处理器的取指地址,根据上述流水线机制,而我们的处理器执行的指令地址是落后于要去预取的指令的地址,落后2个时钟周期。 也就是说我们在取了第一条指令后,等该指令到了执行阶段时,我们的处理器其实已经预取了往后的第二条指令了。 对于32位处理器,一条指令占据4字节。这也就是PC值 = 当前指令地址 + 8的根本原因啦。

Levenberg-Marquardt(LM算法)

 转自: 翠翠的博客 什么是最优化,可分为几大类? 答:Levenberg-Marquardt算法是最优化算法中的一种。最优化是寻找使得函数值最小的参数向量。它的应用领域非常广泛,如:经济学、管理优化、网络分析、最优设计、机械或电子设计等等。 根据求导数的方法,可分为2大类。第一类,若f具有解析函数形式,知道x后求导数速度快。第二类,使用数值差分来求导数。 根据 使用模型不同,分为非约束最优化、约束最优化、最小二乘最优化。 什么是Levenberg-Marquardt算法? 它是使用最广泛的非线性最小二乘算法,中文为列文伯格-马夸尔特法。它是利用梯度求最大(小)值的算法,形象的说,属于“爬山”法的一种。它同时具有梯度法和牛顿法的优点。当λ很小时,步长等于牛顿法步长,当λ很大时,步长约等于梯度下降法的步长。在作者的科研项目中曾经使用过多次。图1显示了算法从起点,根据函数梯度信息,不断爬升直到最高点(最大值)的迭代过程。共进行了12步。(备注:图1中绿色线条为迭代过程)。 图1 LM算法迭代过程形象描述 图1中,算法从山脚开始不断迭代。可以看到,它的寻优速度是比较快的,在山腰部分直接利用梯度大幅度提升(参见后文例子程序中lamda较小时),快到山顶时经过几次尝试(lamda较大时),最后达到顶峰(最大值点),算法终止。 如何快速学习LM算法? 学 习该算法的主要困难是入门难。 要么国内中文教材太艰涩难懂,要么太抽象例子太少。目前,我看到的最好的英文入门教程是K. Madsen等人的《Methods for non-linear least squares problems》本来想把原文翻译一下,贴到这里。请让我偷个懒吧。能找到这里的读者,应该都是E文好手,我翻译得不清不楚,反而事倍功半了。 可在 下面的链接中找到 http://www2.imm.dtu.dk/pubdb/public/publications.php? year=&pubtype=7&pubsubtype=&section=1&cmd=full_view&lastndays=&order=author 或者直接下载pdf原文: http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf LM算法是介于牛顿法与梯度下降法之间的一种非线性优化方法,对于过参数化问题不敏感,能有效处理冗余参数问题,使代价函数陷入局部极小值的机会大大减小,这些特性使得LM算法在计算机视觉等领域得到广泛应用。 算法流程 在LM算法中,每次迭代是寻找一个合适的阻尼因子λ,当λ很小时,算法就变成了GAuss-Newton法的最优步长计算式,λ很大时,蜕化为梯度下降法的最优步长计算式。 参考文献: [1]. 张鸿燕, 狄征. Levenberg-Marquardt算法的一种新解释. 计算机工程与应用,2009,45(19),5-8. from: http://heleiying.blog.163.com/blog/static/3110429201081693815164/ Levenberg-Marquardt快速入门教程(荐) 例子程序(MATLAB源程序) 本程序不到100行,实现了求雅克比矩阵的解析解,Levenberg-Marquardt最优化迭代,演示了如何求解拟合问题。采用萧树铁主编的《数学试验》(第二版)(高等教育出版社)中p190例2(血药浓度)来演示。在MATLAB中可直接运行得到最优解。 ************************************************************************* % 计算函数f的雅克比矩阵,是解析式 syms a b y x real; f=a*exp(-b*x); Jsym=jacobian(f,[a b]) % 拟合用数据。参见《数学试验》,p190,例2 data_1=[0.25 0.5 1 1.5 2 3 4 6 8]; obs_1=[19.21 18.15 15.36 14.

date 和 hwclock 命令 (RTC用的着)

http://blog.chinaunix.net/space.php?uid=24148050&do=blog&id=105788 最近在搞RTC,常用的两个命令式 date 和 hwclock。 date命令:操作内核时间(可以理解为软件时间) #date -s 20110120 //设置成日期为 2011年01月20号,这样会把具体时间设置成空00:00:00 #date -s 12:23:23 //设置具体时间,不会对日期做更改 #date -s "12:12:23 2011-01-20" //设置日期和具体时间 hwclock命令:操作硬件RTC芯片时间(可以理解为硬件时间) 功能说明:显示与设定硬件时钟。 语 法:hwclock [--adjust][--debug][--directisa][--hctosys][--show][--systohc][--test] [--utc][--version][--set --date=<日期与时间>] 补充说明:在Linux中有硬件时钟与系统时钟等两种时钟。硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟。系统时钟则是指 kernel中的时钟。当Linux启动时,系统时钟会去读取硬件时钟的设定,之后系统时钟即独立运作。所有Linux相关指令与函数都是读取系统时钟的设定。 参 数: --adjust hwclock每次更改硬件时钟时,都会记录在/etc/adjtime文件中。使用--adjust参数,可使hwclock根据先前的记录来估算硬件时钟的偏差,并用来校正目前的硬件时钟。 --debug 显示hwclock执行时详细的信息。 --directisa hwclock预设从/dev/rtc设备来存取硬件时钟。若无法存取时,可用此参数直接以I/O指令来存取硬件时钟。 --hctosys 将系统时钟调整为与目前的硬件时钟一致。 --set --date=<日期与时间> 设定硬件时钟。 --show 显示硬件时钟的时间与日期。 --systohc 将硬件时钟调整为与目前的系统时钟一致。 --test 仅测试程序,而不会实际更改硬件时钟。 --utc 若要使用格林威治时间,请加入此参数,hwclock会执行转换的工作。 --version 显示版本信息

C# 发送Post请求(带参数)

此处内容传输都是用UTF-8编码 1.不带参数发送Post请求 /// <summary> /// 指定Post地址使用Get 方式获取全部字符串 /// </summary> /// <param name="url">请求后台地址</param> /// <returns></returns> public static string Post(string url) { string result = ""; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); Stream stream = resp.GetResponseStream(); //获取内容 using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) { result = reader.ReadToEnd(); } return result; } 2.带参数Post请求,指定键值对 /// <summary> /// 指定Post地址使用Get 方式获取全部字符串 /// </summary> /// <param name="url">请求后台地址</param> /// <returns></returns> public static string Post(string url,Dictionary<string,string> dic) { string result = "

Object-C基础(15)——NSBundle与对象归档

NSBundle NSBundle:它也是用于进行资源访问的API,它主要用于访问项目内部的资源。 开发了一个APP,游戏,它们肯定会包含大量的资源:图片、音效、地图文件、模型文件…… 对于这些资源的管理,肯定涉及如下问题: 1. 如果使用绝对路径来存放资源,当这个应用发布到客户端时,这些资源文件如何保证也正确地安装到了客户端。 2. 当程序访问这些资源时,怎么保证这些资源也位于正确的位置。 很多时候,会直接把一些应用常见的资源,直接打包在应用里面。 主流用法: (1)调用mainBundle方法来获取NSBundle对象。 (2)pathForResource:ofType或URLForResourceofType:使用NSBundle来获取指定资源的Path或URL。 (3) 拿到资源的Path或URL之后,程序即可通过该Path或URL来访问资源内容。 NSBundle的主要作用是获取指定资源的Path或URL,它并不能访问资源的内容。如果要访问内容, 还是用之前介绍的,NSString、NSArray、NSDictionary、NSFileManager、NSFileHandle……这样一些工具类。 对象归档 对象,本来是保存内存中的,具有瞬时性(瞬态) —— 当程序退出、机器断电时,对象就会从内存中消失。 有时候,程序需要把对象“永久”地保存下来。因此需要把对象保存到“硬盘”类似的物理存储设备、甚至通过网络传输。 对象归档(序列化): -------------> 内存中对象 磁盘(网络)上的数据 <------------- 对象归档主要用到2个类: - NSKeyedArchiver:负责归档。 把对象转化成磁盘或网络上的数据。 - NSKeyedUnarchiver:负责反归档。 把磁盘或网络上的数据转换成对象。 使用NSKeyedArchiver归档: A。 直接调用+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path 或 + (NSData *)archivedDataWithRootObject:(id)rootObject 方法进行归档。 上面的第一个方法,直接将对象转换成磁盘上的二进制数据。简单、直观。 第二个方法,将对象转换成内存中二进制数据(NSData),接下来即可把该数据通过网络发送,也可保存到磁盘上。 通过A方式进行归档,会导致内存中每个对象都会生成一份对应的二进制数据。 B。 以指定NSMutableData为参数,创建NSKeyedArchiver。 接下来程序依次通过NSKeyedArchiver对N个对象进行归档,所有对象,都会被归档到NSMutableData中, 归档完成之后,调用NSKeyedArchiver的finishEncoding结束归档即可。所有对象数据都在NSMutableData中 使用NSKeyedUnarchiver反归档: 与归档时所采用的方式对应,如果归档时使用了A方式,此处也应该使用A方式进行反归档; 如果归档时使用了B方式,此处也应该使用B方式进行反归档; A方式,每个数据中只包含一个归档对象时, 程序调用unarchiveObjectWithFile:或unarchiveObjectWithData:方法进行反归档。 B方式,数据中包含多个归档对象时, 程序调用unarchiveObjectWithFile:或unarchiveObjectWithData:方法进行反归档。 以指定NSData为参数,创建NSKeyedUnarchiver。 接下来程序依次通过NSKeyedUnarchiver对N个对象根据key进行反归档,所有对象,都会被归档到NSMutableData中, 归档完成之后,调用NSKeyedArchiver的finishEncoding结束归档即可。所有对象数据都在NSMutableData中 对于B种方式,归档和反归档的顺序并不需要一致——因为都是按归档对象的key来进行的。 自定义类的归档 如果一个类需要能被归档,该类必须满足如下2个要求: - 遵守NSCoding协议。 - 并实现NSCoding协议中2个方法。 其中:- (void)encodeWithCoder: 负责将对象转成二进制数据。

Oracle 11.2 GI中OLR损坏的修复方法

一、先关闭GI,命令不再贴出来了,参见: http://blog.csdn.net/msdnchina/article/details/49402299 二、模拟OLR损坏 [root@hostb cdata]# ls -lrt total 2884 drwxr-xr-x 2 grid oinstall 4096 Oct 30 13:21 hostb drwxr-xr-x 2 grid oinstall 4096 Oct 30 19:06 localhost drwxrwxr-x 2 grid oinstall 4096 Dec 22 13:27 hosta-cluster -rw------- 1 root oinstall 272756736 Jan 8 13:38 hostb.olr [root@hostb cdata]# mv hostb.olr back_hostb.olr -----------> mv掉OLR [root@hostb cdata]# ls -lrt total 2884 drwxr-xr-x 2 grid oinstall 4096 Oct 30 13:21 hostb drwxr-xr-x 2 grid oinstall 4096 Oct 30 19:06 localhost drwxrwxr-x 2 grid oinstall 4096 Dec 22 13:27 hosta-cluster -rw------- 1 root oinstall 272756736 Jan 8 13:38 back_hostb.

FTP上传

boolean success = false; FTPClient ftp = new FTPClient(); try { int reply; ftp.connect(url, port);//链接ftp服务器 ftp.login(username, password); reply = ftp.getReplyCode(); if(!FTPReply.isPositiveCompletion(reply)){ ftp.disconnect(); return success; } ftp.changeWorkingDirectory(path); ftp.storeFile(fileName, input); input.close(); ftp.logout(); success=true; } catch (Exception e) { e.printStackTrace(); } finally{ if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { ioe.printStackTrace(); } } } return success; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ try { /*File file = new File("D:/test.txt"); file.createNewFile();*/ // FileInputStream in=new FileInputStream(file); String url="

NRF24L01程序模板(STC89C51)

1 #include <REGX52.H> 2 #include "nrf24l01.h" 3 #define unint unsigned int 4 #define unchar unsigned char 5 sbit led1=P2^6; 6 sbit led2=P2^7; 7 sbit key1=P3^0; 8 sbit key2=P3^1; 9 sbit key3=P3^2; 10 sbit key4=P3^3; 11 void keyscan(); 12 unchar dat[1]; 13 void delay(unchar x) 14 { 15 unchar i,j; 16 for(i=x;i>0;i--) 17 for(j=100;j>0;j--); 18 } 19 void main() 20 { 21 22 //dat[0]=0xff; 23 NRF24L01Int(); 24 led1=1;led2=1; 25 while(1) 26 { 27 // keyscan(); 28 dat[0]=0x02; 29 NRFSetTxMode(dat); 30 while(CheckACK()); 31 } 32 } 33 34 void keyscan() 35 { 36 if(key1==0) 37 { 38 delay(200); 39 if(key1==0) 40 { 41 while(key1==0); 42 // dat[0]=0xff; 43 // NRFSetTxMode(dat); 44 // while(CheckACK()); 45 46 // led1=~led1; 47 } 48 } 49 50 if(key2==0) 51 { 52 delay(200); 53 if(key2==0) 54 { 55 56 // dat[0]=0xff; 57 // NRFSetTxMode(dat); 58 // while(CheckACK()); 59 dat[0]=0x02; 60 NRFSetTxMode(dat); 61 while(CheckACK()); 62 // led1=~led1; 63 } 64 } 65 66 if(key3==0) 67 { 68 delay(200); 69 if(key3==0) 70 { 71 dat[0]=0x03; 72 NRFSetTxMode(dat); 73 while(CheckACK()); 74 } 75 } 76 77 if(key4==0) 78 { 79 delay(200); 80 if(key4==0) 81 { 82 dat[0]=0x04; 83 NRFSetTxMode(dat); 84 while(CheckACK()); 85 86 } 87 } 88 } 上面是主程序send.

绘制矩形

1.与矩形有关的方法:fillRect() strokeRect() clearRect() 这三个方法都能接受四个参数:矩形的x坐标,矩形的y坐标,矩形的宽度和矩形的高度;单位都是像素 2 //绘制红色矩形. 填充为红色;从点(10,10)开始绘制矩形,宽和高均为50像素, context.fillStyle="#ff0000"; context.fillRect(10,10,50,50); //绘制蓝色矩形 然后填充被设置成了半透明的蓝色 从点(30,30)开始绘制,宽和高为50像素 context.fillStyle="rgba(0,0,255,0.5)"; context.fillRect(30,30,50,50); //绘制红色描边矩形 context.strokeStyle="#ff0000"; context.strokeRect(10,10,50,50); //绘制蓝色描边矩形 context.strokeStyle="rgba(0,0,255,0.5)"; context.strokeRect(30,30,50,50); 3. lineWidth;描边线条的粗细 值可以是任意整数; lineCap:控制线条末端的形状是平头,圆头,还是方头 “butt" "round" "square" lineJoin:控制线条相交的方式是圆交,斜交,还是斜接 round bevel miter 4.context.clearRect(10,10,30,30) 从点(10,10)开始的宽30 高30 的矩形清除掉 转载于:https://www.cnblogs.com/suxiaozhen/p/5316339.html

Boost无锁队列

在开发接收转发agent时,采用了多线程的生产者-消费者模式,用了加互斥锁的方式来实现线程同步。互斥锁会阻塞线程,所以压测时,效率并不高。所以想起用无锁队列来实现,性能确实提升了。 首先介绍下lock-free和wait-free的区别: 阻塞算法可能会出现整个系统都挂起的情况(占有锁的线程被中断,无法释放所,那么所有试图争用这个锁的线程会被挂起),系统中的所有线程全部饿死。 无锁算法可以保证系统中至少有一个线程处于工作状态,但是还是可能有线程永远抢不到资源而被饿死。 无等待算法保证系统中的所有线程都能处于工作状态,没有线程会被饿死,只要时间够,所有线程都能结束。相比于无锁算法,无等待算法有更强的保证。 一. 用互斥锁实现单生产者-单消费者 #include <string> #include <sstream> #include <list> #include <pthread.h> #include <iostream> #include <time.h> using namespace std; int producer_count = 0; int consumer_count = 0; list<string> product; list<string> consumer_list; pthread_mutex_t mutex; const int iterations = 10000; //是否生产完毕标志 bool done = false; void* producer(void* args) { for (int i = 0; i != iterations; ++i) { pthread_mutex_lock(&mutex); int value = ++producer_count; stringstream ss; ss<<value; product.push_back(ss.str()); //cout<<"

SVN检出maven项目,目录结构不对,解决方法(更新)

原方法: --------------------------------------------------------------------------------------------------- 检出maven项目后,右击删除(不要删除本地文件) 然后在import ---------existing maven project 即可解决目录结构不对的问题 --------------------------------------------------------------------------------------------------- 更好的方法: --------------------------------------------------------------------------------------------------- 检出maven项目后,右击项目选择configure----convert to maven project 即可解决。 ---------------------------------------------------------------------------------------------------