安装提示错误 [INSTALL_FAILED_OLDER_SDK]的解决方案

原先在1.6rc1上写的程序,拿到1.5的SDK重新编译后却不能用 abd install bin/xxx.apk 安装上去,提示错误是: Failure [INSTALL_FAILED_OLDER_SDK] 找了一下,是这个原因: 打开源码目录下的AndroidManifest.xml文件,然后注释掉或者删除掉这行: <uses-sdk android:minSdkVersion="4" /> 另一篇文章: 通过在manifest中添加android.uid.system和在Android.mk中添加LOCAL_CERTIFICATE := platform,然后MMM编译以获取次特权。但是我通过MMM编译出来的APK不能在系统提供的SDK中创建的AVD里安装,提示Failure [INSTALL_FAILED_OLDER_SDK] 解决方法: /build/core/version_defaults.mk文件中这一段 ifeq "" "$(DEFAULT_APP_TARGET_SDK)" # This is the default minSdkVersion and targetSdkVersion to use for # all .apks created by the build system. It can be overridden by explicitly # setting these in the .apk's AndroidManifest.xml. It is either the code # name of the development build or, if this is a release build, the official

Nginx出现“ 413 (499 502 404) Request Entity Too Large”错误解决方法

1.Nginx413错误的排查:修改上传文件大小限制 在使用上传POST一段数据时,被提示413 Request Entity Too Large,应该是nginx限制了上传数据的大小。 解决方法就是 打开nginx主配置文件nginx.conf,一般在/usr/local/nginx/conf/nginx.conf这个位置,找到http{}段,修改或者添加:client_max_body_size 2m; 如图: 然后重启nginx: 2.Proxy缓冲不够 如果你使用了Proxying,请把 proxy_buffer_size 16k; proxy_buffers 4 16k; 这几项的值调高 来源:http://www.ruby-forum.com/topic/169040 3.Nginx 400错误排查:HTTP头/Cookie过大 今天有人汇报nginx的HTTP400错误,而且这个HTTP400错误并不是每次都会出现的,查了一下发现nginx400错误是由于request header过大,通常是由于cookie中写入了较长的字符串所引起的。 解决方法是不要在cookie里记录过多数据,如果实在需要的话可以考虑调整在nginx.conf中的client_header_buffer_size(默认1k) 若cookie太大,可能还需要调整large_client_header_buffers(默认4k),该参数说明如下: 请求行如果超过buffer,就会报HTTP 414错误(URI Too Long) nginx接受最长的HTTP头部大小必须比其中一个buffer大,否则就会报400的HTTP错误(Bad Request)。 4.参数都有所调整.目的是解决代理过程中出现的一些502 499错误 user www www; worker_processes 4; # [ debug | info | notice | warn | error | crit ] error_log /usr/local/webserver/nginx/logs/nginx_error.log crit; pid /usr/local/webserver/nginx/nginx.pid; #Specifies the value for maximum file descriptors that can be opened by this process.

ffmpeg中如何加入trueHD/mlp编码器

在ffmpeg标准版中已经存在mlp音频解码器,但却没有编码器,但在soc版本中是有的,且有一个专门的目录mlp存放。 和其它编码器,mlp编码的相关文件是mlpenc.h和mlpenc.c,但在soc中不能直接加入,需要在接口上加以更改,改接口是mlp_encode_frame,细心的开发人员不难发现,他们是不一样的。 在soc或早期版本中如下: int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); 后来使用了encode2,其定义如下: int(*encode2)(AVCodecContext*avctx, AVPacket*avpkt, constAVFrame*frame, int*got_packet_ptr); 在avcodec.h中当然也必须更改REGISTER_DECODER(MLP,mlp)更改为REGISTER_ENCDEC(MLP, mlp). 有测试过的同学也发现这个mlp编码器并不能在ts或m2ts中进行复用流的编码,这是因为在复合流中使用的是其复杂形式,名称为trueHD. 所以在同步头中还应根据mlp还是trueHD作一点更改,当然这一点根据只能编码出trueHD的裸流音频。 如果直接使用-i filename -avcodec truehd -ac2 outpath/outname.m2ts,播放时会没有声音,这是为什么呢? 这是因为在ffmpeg中并没有对turehd的流进行标识,正确的做法是在节目表中写入truehd的标识0x83,如此便能成功。 补充说明:mlp的fourCC('M','L','P',' ' ), trueHD的fourCC('T','R','H','D').

程序员——伤不起的三十岁

程序员干到30岁,好不容易从码奴混到了白领,却再也干不动了,还时时面临失业的危险。30岁,是一个程序员伤不起的年龄。明天,何去何从? 一.30岁现象 在官场上,曾经有一个59岁现象,就是官员们会在59岁时,会使劲捞上一把。很明显嘛,权力过期作废,再不捞就要退休了,没有机会了。 在程序员的圈子里,也有一个30岁现象。当然,如果你有铁饭碗,比如在国企或政府机关,那你是无法理解底层劳动人民的感受的。同时也要恭喜你成为体制内的一员,可以一直干到退休无忧。 30岁现象人人都明白,但要给出一个定义并不容易。列举几个表现,也许你会觉得心有戚戚焉。 面临职业瓶颈,程序写不动,上升又困难。 薪水较高,加班变少,后浪追前浪,面临失业压力; 生活压力剧增,不敢跳槽; 招聘程序员年龄限制在30岁以下成为行业潜规则,跳槽困难。 30 岁现象和59岁现象貌似不搭边,其实都出于同样的原因:价值贬值。官员老爷在任就像皇帝,一旦退休,就成为了平民百姓,贬值那是自然的。而程序员也一样, 所谓三十而立,一旦到了30岁左右,由于面临结婚生子,一方面需要高薪抚养家庭,另一方面却无法像以前那样全身心投入到工作,性价比急剧下降;与此同时, 大批廉价的新手涌入,他们往往还使用最新的技术,老一辈程序员只能慢慢的靠边站了。 二.不可替代性 30岁现象产生,只能程序员自身身上找原因。 当然我们也可以产业、从社会、从政府、从制度等多方面进行分析,发现不足,这些分析未必没有道理,但是肯定没有用,因为我们无法改变。所谓“命苦不能怪政府,命背不能怪社会”,从外部找原因,只会让我们满腹牢骚,整天觉得自己生不逢时,苦闷不堪。 从自身找原因,试着问自己几个问题:“为什么我的性价比以下降?老板为什么要请我,给我高工资呢?一个人有价值是由什么决定的呢?” 你也许可以列出很长很长的答案,但我想应该都可以浓缩为一句话:“一个的价值是由他的不可替代性决定的”。不可替代性可以理解为,为了替代你老板需要付出的代价。 因为你的可替代性高,所以性价比下降。反之,因为你不可替代性高,所以老板会给你开高工资。不是这样的吗? 有一则小故事: 技师退休时告诫自己的徒弟:“少说话,多做事。”十年后徒弟也成了技师,他找到师傅,苦着脸说:“师傅,我一直都按您的教导做,只知埋头苦干,可那些比我技术差的都升职了、加薪了,我还是拿着过去的工资。” 师傅想了想,说:“你请一次假吧。如果一盏灯一直亮着,那就没人会注意到它……” 徒弟恍然大悟,真的请了一星期假,等他回去上班时,厂长找到他说要给他加薪。原来,在他请假时,厂长发现,工厂已经离不开他了。 徒弟很高兴,以后他时不时就请几天假,每次请假后厂长都会给他加薪。一天徒弟请假后准备去上班,厂长却告诉他:“你不用来上班了。” 徒弟苦恼地去找师傅,师傅说:“那天我的话还没说完呢。一盏灯偶尔可以熄灭一次,可如果它总是熄灭,性质就不一样了,因为没人会需要一盏时亮时熄的灯。” 故事中,因为徒弟的不可替代,所以厂长给他加薪;后来因为有其它的灯亮了,他被替代了,厂长不需要他了,所以被炒了鱿鱼。 所以我们归根到底还是要提高自己的不可替代性。否则,一旦老板觉得用较低的代价就可以替代你,那么你就面临可能失业的危险了。 三.出路在哪里 那程序员到了30岁,怎样提高自己的不可替代性呢?我们打算做一辈子程序员吗?敢问路在何方? 作为一个过来人、一个资深程序员,我觉得有几个方向可以选择: (1)成为技术大拿 其实,做一辈子程序员并没有什么问题,重要的是,你必须成为一个不可替代的程序员,也就是说,你要成为技术大拿,能够解决普通程序员所不能解决的问题。技术大拿有两个版本: 一 是程序员加强版。你仍然是一个程序员,但你是一个很牛的程序员,凭借多年的积累,你在知识广度和深度方面均已不是等闲之辈。从汇编到java,你样样精 通。你在意数据结构和算法,对系统的优化有独到见解,对设计模式如数家珍,你还有完备的工具箱和自己的专用类库。其实,加强版程序员有非常独特的价值,可 惜的是,在现实中却很少见,因为对任何一个公司而言,人才总是很稀缺的。老板的眼睛是雪亮的,他怎么会对你这种技术大牛视而不见呢,在你还没有成为真正的 大拿之前,早已经被任命为系统架构师、项目经理或者更高的职位了。因此,你想守住自己的一亩三分地,悠闲的做自己的大拿,往往是不可能的。 二 是程序员升级版。虽然你的内在仍然是一个程序员,但你的职位已经升级了,你成为了系统分析师或系统架构师。这是非常自然和现实的选择。程序员与系统分析师 或架构师之间并有鸿沟,只需一步而已,你就可以从崎岖山路驶向宽阔的大马路。但这一步却并不容易,需要几年时间不断思考、学习、实践,才能化蛹成蝶。 (2)成为行业专家 行 业专家也是一个公司不可缺少的角色,他们对公司的行业知识、业务流程和细节了如指掌。行业专家一般并不是从外部招聘的一个只懂业务、不懂技术的超人,而往 往是从程序员经过多年的摸爬滚打成长起来的。作为从程序员成长起来的行业专家,你往往还肩负系统分析师之职。在公司里,对业务有一般了解的人很多, 但专 家级别的往往很少,为了后30年的职业生涯,你必须成为专家。 (3)朝管理方向发展 向管理方向发展的第一步,一般是被任命为项目经理。在大部分IT公司里, 项目经理是最小的管理岗位了,可能你不会觉得有太多惊喜,工资也没有大的提升,但这个转变,可以说会成为你一生中最重要的转变之一。 不 要小看了项目经理。有人说,项目经理是一个古老的职业。也人有人说,21世纪是项目管理的世纪。事实上,从人类有组织以来,就一直有项目管理,以前的项目 经理可能是部落首领,一次集体打猎、一次攻城拔寨,都可以视为一个项目。项目管理的知识可以应用到我们生活的方方面面,大至登月计划的实施,小至家庭聚会 的组织,都离不开项目管理。 一个优秀的项目经理,不仅需要高智商,还需要高情商。可以不夸张的说,如果你能胜任项目管理,你就可以胜任战术层的所有管理岗位,甚至你有家庭生活质量,也会提高到新层次。 然而,要成为一名优秀的项目经理,并不是一件容易的事情。可以说,需要一定的天分,有些人无师自通,有些人却永远也学不会。程序员属于高智商人群,情商却往往存在不足,这注定了只有少数程序员能够成长为项目经理,成为优秀的项目经理,则非常稀少了。 如果你觉得这几方面都合适,那你还有几条出路: 一是塌塌实实混日子。 说老实话,做老实人,办老实事,拿老实的工资,这种员工公司也是非常需要的,一般不会遭遇炒鱿鱼的命运; 二是转行或者创业。 因 为这个行业已经不再适合你,已经没有更大的发展前途,只能转行。如果可以转行,未必是坏事,也许在新的环境中,可以激发出更强的能量,创造出一番事业来。 至于创业,那就更具有挑战性了,建议你在创业之前,已经成为了一名优秀的项目经理。试想,如果转不动一个项目,如何能转动一个公司?

学习外挂编写开发所必备技术

一直敬佩计算机技术高超的黑客,不是羡慕他们能盗窃别人的资料,是对于一行行姿态优美的计算机代码情有独钟,而这些代码在黑客手中则能活灵活现的完成各种奇迹般的动作。 个人能力有限,不能学得一身编程本领,但不会限制我对电脑技术的一腔热情!自己不能创作作品,于是转载相关资料是我满足阅读欲望的一种途径。 注:下面内容转自互联网(同学手机上的电子书,不知道具体出处,谁知道,帮忙附在后面。) 一、先说一下写一个外挂需要什么条件 1、熟练的C语言知识 目前的外挂大部分都是用BC或者是vc写的,拥有熟练的C语言知识是写外挂的基本条件。 2、具有很强的汇编基础 一般游戏都不可能有原代码的,必须靠反汇编或者跟踪的办法来探索其中的机理,所以有强的汇编基础也是必不可少的条件。 3、熟练掌握跟踪和调试的工具 有了上面2个条件后,掌握一些工具也是很有必要的跟踪的工具,softice当然是不二之选,至于反汇编的工具,我推荐用IDA PRO这个工具反汇编出来的代码结构清晰,非常好读。 如果你不具有上面的条件,还是先把基础打好,再来写外挂吧,一分耕耘,一分收获,天下没有白掉的馅饼的。 二、写外挂面临的基本技术问题 1、修改进程的执行代码 要修改进程的执行代码,要先取得进程的ID,如果是由外挂程序启动,返回值里就有进程ID,如果不是的话,需要用findwindow找到窗口句柄,再用GetWindowProcessID取得进程ID,取得进程ID以后,就可以用 writeprocessmemory来修改进程的执行代码了,使程序按照我们的意愿来执行,石器外挂里的不遇敌、寸步遇敌就是用这样的方法来实现的。 2、截获外挂发送和接收的封包 除了通过修改代码来实现的功能以外,很多的功能都是通过修改封包来实现的,要修改封包,首先要能截获它。第一步是要跟踪出发和收的位置,至于怎么跟踪,我以后会提到,找到位置以后,有2个办法,一是在那个位置加一个jmp语句,跳到你的处理函数位置,处理完后,再跳回来,这种方法要求比较高,需要处理好很多事情,另一种办法是往那个位置写条能造成例外的指令,比如int 3,然后用DebugActiveProcess调试游戏进程,这样每当游戏执行到那个位置的时候,就会停下来,到外挂程序里面去,等外挂程序处理完以后,用ContinueDebugEvent 继续运行程序。 今天先写这么多,下回将讨论外挂的具体功能该怎么实现今天来谈谈地址的调查问题,地址调查是写外挂中最艰辛,最富有挑战性的事情,很多朋友问我要外挂的原程序,其实有了外挂原程序,如果你不会调查地址,还是没用的,原程序和地址的关系就象武学中招式与内功的关系,没有内功的招式,只是一个花架子。而内功精深以后,任何普通的招式,都有可能化腐朽为神奇,外挂中的地址分为两类,一类是程序地址,一类是数据地址。象石器中的双石器,真彩,不遇敌,寸步遇敌,发送接收封包等,都属于第一类,而人物坐标,状态等,都属于第二类。对于第一类地址,主要依靠softice来调查地址,对第二类地址,可以用一些游戏工具,比如fpe,game expert,game master等来调查,我一直用game expert,因为我找不到2000下能用的fpe, 各位以前用fpe改游戏的时候,没想过他也能用来干这个吧 对于第二类数据的调查方法,大部分人都很熟习了,我就不多说了,现在主要来谈谈第一类数据的详细调查过程,比如我们要调查发送封包的位置,如何着手呢,客户端往服务器要发很多封包,但最简单的办法莫过从说话的封包入手,先说一句很长的话,最好是英文,查起来方便,说完以后,用任意一种办法进入游戏程序的进程空间(比如先用spy查出游戏程序的窗口句柄,再切换到softice打入bmsg 窗口句柄 wm_lbuttondown,这样在游戏程序中一点鼠标就进入了他的进程空间)然后用s命令查出这句话所放的内存地址,记下这个地址,在softice中打入bpm 刚才调查到的地址,这个指令的意思是只要有访问这个内存的动作,立刻中断,然后再切换到游戏,说一句话,你会发现softice自动中断到某一个位置了,从这个位置跟踪下去,发送封包的位置也就不远了。 上面所说的都是针对一个全新的游戏程序而言,如果是一个老的程序,有前辈做了大量的工作,还可以用些别的办法,如反汇编等,来调查。以后游戏版本的更新也是如此,只要把老版本的地址位置附近的代码记下来,去新版本的代码里面search一下,就ok了。 我主要对外挂的技术进行分析,至于游戏里面的内部结构每个都不一样,这里就不做讲解了,我也没有那么厉害,所有的都知道,呵呵! 1 首先游戏外挂的原理 外挂现在分为好多种,比如模拟键盘的,鼠标的,修改数据包的,还有修改本地内存的,但好像没有修改服务器内存的哦,呵呵!其实修改服务器也是有办法的,只是技术太高一般人没有办法入手而已!(比如请GM去夜总会,送礼,收黑钱等等办法都可以修改服务器数据,哈哈) 修改游戏无非是修改一下本地内存的数据,或者截获api函数等等,这里我把所能想到的方法都作一个介绍,希望大家能做出很好的外挂来使游戏厂商更好的完善自己的技术. 我见到一片文章是讲魔力宝贝的理论分析,写的不错,大概是那个样子. 下来我就讲解一下技术方面的东西,以作引玉之用 2 技术分析部分 1 模拟键盘或鼠标的响应 我们一般使用UINT SendInput( UINT nInputs, // count of input events LPINPUT pInputs, // array of input events int cbSize // size of structure );api函数 第一个参数是说明第二个参数的矩阵的维数的,第二个参数包含了响应事件,这个自己填充就可以,最后是这个结构的大小,非常简单,这是最简单的方法模拟键盘鼠标了,呵呵 注意:这个函数还有个替代函数: VOID keybd_event( BYTE bVk, // 虚拟键码 BYTE bScan, // 扫描码 DWORD dwFlags, ULONG_PTR dwExtraInfo // 附加键状态 );和 VOID mouse_event( DWORD dwFlags, // motion and click options DWORD dx, // horizontal position or change DWORD dy, // vertical position or change DWORD dwData, // wheel movement ULONG_PTR dwExtraInfo // application-defined information ); 这两个函数非常简单了,我想那些按键精灵就是用的这个吧,呵呵,上面的是模拟键盘,下面的是模拟鼠标的.

Ubuntu 输入正确的账号密码,登陆后又跳回到登录界面 解决方案

启动系统,输入正确的账号和密码,点击登录,屏幕一闪,然后又跳回登录界面。 百度、谷歌了好久,各家有各家的说法,也许是症状相同,病因不同吧,按照网上的解决方案,始终解决不了,最终,经过不懈的尝试,发现了解决方案,为了防止下次忘记,在此记录一下,同时,感谢作者。 原因:主目录下的.Xauthority文件拥有者变成了root,从而以用户登陆的时候无法都取.Xauthority文件。 说明:Xauthority,是startx脚本记录文件。Xserver启动时,读文件~/.Xauthority,读入对应其display的记录。当一个需要显示的客户程序启动调用XOpenDisplay()也读这个文 件,并把找到的magic code 发送给Xserver。当Xserver验证这个magic code正确以后,就同意连接啦。观察startx脚本也可以看到,每次startx运行,都在调用xinit以前使用了xauth的add命令添加了一个新的记录到~/.Xauthority,用来这次运行X使用认证 解决方法:我们需要将.Xauthority的拥有者改为登陆用户(或者干脆将.Xauthority删除,此法转自网上,本人未验证) 开机后在登陆界面按下shift + ctrl + F1进入tty命令行终端登陆后输入:(本人的用户名为hp,因此chown后面跟了hp:hp若为其他用户名修改成相应的名称即可) $ cd ~ $ sudo chown hp:hp .Xauthority 然后再次输入: ls .Xauthority -l 成功后显示如下: -rw------- 1 hp hp 80 1月 27 10:41 .Xauthority 此时拥有者已经变为用户。按下shift + ctrl + F7切换回图形登陆界面登陆即可。 转载:http://blog.163.com/thinki_cao/blog/static/8394487520130270379437/

[Linux]socket阻塞模式下recv()返回11(EAGAIN )的原因

linux socket 阻塞模式下recv()返回11(EAGAIN )的可能原因: 1,设置了接收超时为非0。 参考至:http://stackoverflow.com/questions/735249/blocking-socket-returns-eagain 2,网络质量差,例如:wifi环境下的网络信号强度太弱

Android 多线程:使用Thread和Handler

当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。 比如说从网上获取一个图片,在一个ImageView中将其显示出来,这种涉及到网络操作的程序一般都是需要开一个线程完成网络访问,但是在获得图片后,是不能直接在网络操作线程中调用ImageView的相关方法的,因为其他线程中是不能直接访问主UI线程成员 。 完整代码: 注意的是:Manifest.xml文件中,要声明网络权限。 package com.xsjayz.thread; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; /** * 使用Thread+Handler的方式实现在非UI线程发送消息通知UI线程更新界面 * * <a href="http://my.oschina.net/arthor" class="referer" target="_blank">@author</a> XuShaoJie * @version 2012-08-31 */ public class ThreadHandlerActivity extends Activity { private static final int MSG_SUCCESS = 0;// 获取图片成功的标识 private static final int MSG_FAILURE = 1;// 获取图片失败的标识 private ImageView mImageView; private Button mButton; private Thread mThread; @Override public void onCreate(Bundle savedInstanceState) { super.

基于hadoop的多个reduce 输出

import java.io.File; import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapred.JobConf; import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public class MultipOutputWordCount extends Configured implements Tool { /* * Mapper<Object, Text, Text, IntWritable> * Object ,读取的字节偏移量 * Text Map读取的文本行 * Text Map的输出Key * IntWritable 的输出Value */ public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { //一行行读取文件内容,一行行处理文件 StringTokenizer itr = new StringTokenizer(value.

根据XSD定义生成C++类

根据XSD定义生成C++类 可以使用xsdcxx或xsde库 CodeSynthesis XSD/e is an open-source, dependency-free XML Schema to C++ compiler for mobile, embedded, and light-weight applications. It provides XML parsing, serialization, XML Schema validation and XML data binding while maintaining a small footprint and portability. This page contains information for XSD/e compiler developers. For an overview of the XSD/e capabilities refer to the XSD/e product page. License You can use, distribute, and/or modify XSD/e, its runtime library, and the generated code under the terms of the GNU General Public License, version 2 as published by the Free Software Foundation.

普通域账户不能登录域控

今天有个网友问我,自己实验的时候创建的域普通账户登录域控时出错,原因在哪?如何解决? 原因: 出于管理和安全的需要,默认的域控策略不允许普通域账户登录域控; 不建议修改这个默认的策略,但是现实的环境一定要登录,或者实验中想登录,可以通过以下两种方式: (1)赋予这个普通域账户一定权限,即加这个普通域账户到Account Operators/Administrators/Backup Operators/Print Operators/Server Operators中任意一个群组即可; 或者 (2)在域控中打开域策略编辑器,修改默认的域控策略,点中“计算机配置”->“策略”->“Windows设置”->“安全设置”->“本地策略”->“用户权限分配”,可以看到在详细窗口有“允许在本地登录”设置,双击“允许在本地登录”,可以看到Account Operators/Administrators/Backup Operators/Print Operators/Server Operators已经在框中,将这个普通用户加入到这个框中即可; 其实也可以看出(1)(2)是相通的,灵活处理即可; 转载于:https://blog.51cto.com/281816327/1246100

jquery常用见的正则表达式

quickexpr = /^(?:[^<]*(<[ww]+>)[^>]*$|#([w-]+)$)/ (?:…)表示是一个非捕获型 [^<]表示是以"<"起始,包含0个或多个'<'括号 (<[ww]+>)表示是一个捕获型,以'<>'起始,中间包含一个或多个字符 $表示字符的结尾 (#([w-]+))表示是一个捕获型,以'#'号和字符串、数字、_以及-组成 rnotwhite = /s/ s表示是空白字符以外的符号 trimleft = /^s+/trimright = /s+$/ 左右边的空白。s是空白字符。^前缀表示字符串开始,$后缀表示字符串结束 rdigit = /d/ 表示是数字 rsingletag = /^<(w+)s*/?>(?:</1>)?$/ ^<(w+)s*/?> 表示以'<'起始,包含一个到多个字符,以及0个到多个空白,0个或者一个'/'和'>'结束, (?:</1>)?$ 1.非负整数 /^d+$/ 2.正整数 /^[0-9]*[1-9][0-9]*$/ 3.非正整数 /^((-d+)|(0+))$/ 4.负整数 /^-[0-9]*[1-9][0-9]*$/ 5.整数 /^-?d+$/ 6.非负浮点数 /^d+(.d+)?$/ 7.正浮点数 /^(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*))$/ 8.非正浮点数 /^((-d+(.d+)?)|(0+(.0+)?))$/ 9.负浮点数 /^(-(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*)))$/ 10.浮点数 /^(-?d+)(.d+)?$/ 11.数字 /^d+(.{1}d+)?$/ 12.由26个英文字母组成的字符串 /^[a-za-z]+$/ 13.由26个英文字母的大写组成的字符串 /^[a-z]+$/ 14.由26个英文字母的小写组成的字符串 /^[a-z]+$/ 15.由数字和26个英文字母组成的字符串 /^[a-za-z0-9]+$/ 16.由数字、26个英文字母或者下划线组成的字符串 /^w+$/ 17.匹配所有单字节长度的字符组成的字符串 /^[x00-xff]+$/ 18.匹配所有双字节长度的字符组成的字符串 /^[^x00-xff]+$/ 19.字符串是否含有双字节字 /[^x00-xff]+/ 20.email地址 /^[w-]+(.[w-]+)*@[w-]+(.[w-]+)+$/ 或者 /w+([-+.

xtrabackup原理及实施

Xtrabackup是基于InnoDB存储引擎灾难恢复的。它复制InnoDB的数据文件,尽管数据文件在内部是非一致性的,但在执行灾难恢复时可以保证这些数据文件是一致的,并且可用。 官方原理 在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。 Xtrabackup在启动时会记住log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。这时,xtrabackup会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。Xtrabackup必须持续的做这个操作,是因为事务日志是会轮转重复的写入,并且事务日志可以被重用。所以xtrabackup自启动开始,就不停的将事务日志中每个数据文件的修改都记录下来。 上面就是xtrabackup的备份过程。接下来是准备(prepare)过程。在这个过程中,xtrabackup使用之前复制的事务日志,对各个数据文件执行灾难恢复(就像mysql刚启动时要做的一样)。当这个过程结束后,数据库就可以做恢复还原了。 以上的过程在xtrabackup的编译二进制程序中实现。程序innobackupex可以允许我们备份MyISAM表和frm文件从而增加了便捷和功能。Innobackupex会启动xtrabackup,直到xtrabackup复制数据文件后,然后执行FLUSH TABLES WITH READ LOCK来阻止新的写入进来并把MyISAM表数据刷到硬盘上,之后复制MyISAM数据文件,最后释放锁。 备份MyISAM和InnoDB表最终会处于一致,在准备(prepare)过程结束后,InnoDB表数据已经前滚到整个备份结束的点,而不是回滚到xtrabackup刚开始时的点。这个时间点与执行FLUSH TABLES WITH READ LOCK的时间点相同,所以myisam表数据与InnoDB表数据是同步的。类似oracle的,InnoDB的prepare过程可以称为recover(恢复),myisam的数据复制过程可以称为restore(还原)。 Xtrabackup和innobackupex这两个工具都提供了许多前文没有提到的功能特点。手册上有对各个功能都有详细的介绍。简单介绍下,这些工具提供了如流(streaming)备份,增量(incremental)备份等,通过复制数据文件,复制日志文件和提交日志到数据文件(前滚)实现了各种复合备份方式。 自己的理解 Xtrabackup只能备份和恢复InnoDB表,而且只有ibd文件,frm文件它不管,恢复时就需要DBA提供frm。innobackupex可以备份和恢复MyISAM表以及frm文件,并且对xtrabackup也做了很好的封装,所以可以使用innobackupex来备份MySQL数据库。还有一个问题,就是innobackupex备份MyISAM表之前要对全库进行加READ LOCK,阻塞写操作,若备份是在从库上进行的话会影响主从同步,造成延迟。对InnoDB表备份不会阻塞读写。 Xtrabackup增量备份的原理是: 1)首先完成一个完全备份,并记录下此时检查点LSN; 2)然后增量备份时,比较表空间中每个页的LSN是否大于上次备份的LSN,若是则备份该页并记录当前检查点的LSN。 具体来说,首先在logfile中找到并记录最后一个checkpoint(“last checkpoint LSN”),然后开始从LSN的位置开始拷贝InnoDB的logfile到xtrabackup_logfile;然后开始拷贝全部的数据文件.ibd;在拷贝全部数据文件结束之后,才停止拷贝logfile。 所以xtrabackup_logfile文件在并发写入很大时也会变得很大,占用很多空间,需要注意。另外当我们使用--stream=tar或者远程备份--remote-host时默认使用/tmp,但最好显示用参数--tmpdir指定,以免把/tmp目录占满影响备份以及系统其它正常服务。 因为logfile里面记录全部的数据修改情况,所以即使在备份过程中数据文件被修改过了,恢复时仍然能够通过解析xtrabackup_logfile保持数据的一致。 Xtrabackup的增量备份只能用于InnoDB表,不能用在MyISAM表上。采用增量备份MySQL数据库时xtrabackup会依据上次全备份或增量备份目录对InnoDB表进行增量备份,对MyISAM表会进行全表复制。 流备份(streaming)可以将备份直接保存到远程服务器上。 当执行恢复时,由于复制是不锁表的所以此时数据文件都是不一致的,xtrabackup使用之前保存的redo log对各个数据文件检查是否与事务日志的checkpoint一致,执行恢复: 1)根据复制数据文件时以及之后已提交事务产生的事务日志进行前滚; 2)将未提交的事务进行回滚。 这个过程就是MySQL数据库宕机之后执行的crash recovery。 增量备份 在InnoDB中,每个page中都记录LSN信息,每当相关数据发生改变,page的LSN就会自动增加,xtrabackup的增量备份就是依据这一原理进行的。Xtrabackup将上次备份(完全备份集或者也是一个增量备份集)以来LSN改变的page进行备份。 所以,要做增量备份第一次就要做一个完全备份(就是将MySQL实例或者说要备份的数据库表做一个完全复制,同时记录LSN),之后可以基于此进行增量备份以及恢复。 增量备份优点: 1)数据库太大没有足够的空间全量备份,增量备份能有效节省空间,并且效率高。 2)支持热备份,备份过程不锁表(针对InnoDB而言),不阻塞数据库的读写。 3)每日备份只产生少量数据,也可采用远程备份,节省本地空间。 4)备份恢复基于文件操作,降低直接对数据库操作风险。 5)备份效率更高,恢复效率更高。 恢复与还原 backup的恢复过程中包括恢复和还原两个部分。 我们前面已经说了xtrabackup只备份InnoDB表的ibd文件,而innobackupex可以备份包括InnoDB表在内的其他存储引擎的表的所有数据文件。由于不同引擎表备份时的不同,也会让恢复过程看起来不一样。 先来看看完全备份集的恢复。 在InnoDB表的备份或者更直接的说ibd数据文件复制的过程中,数据库处于不一致的状态,所以要将xtraback_logfile中尚未提交的事务进行回滚,以及将已经提交的事务进行前滚, 使各个数据文件处于一个一致性状态,这个过程叫做“准备(prepare)”。 如果你是在一个从库上执行的备份,那说明你没有东西需要回滚,只是简单的apply redo log就可以了。另外在prepare过程中可以使用参数--use-memory增大使用系统内存量从而提高恢复速度。 之后,我们就可以根据backup-my.cnf中的配置把数据文件复制回对应的目录了,当然你也可以自己复制回去,但innobackupex都会帮我们完成。在这里,对于InnoDB表来说是完成“后准备”动作,我们称之为“恢复(recovery)”,而对于MyISAM表来说由于备份时是采用锁表方式复制的,所以此时只是简单的复制回来,不需要apply log,这个我们称之为“还原(restore)”。 注:本文档里之所以使用恢复和还原,也是和其他数据库比如Oracle看起来一样。 对于增量备份的恢复过程,与完全备份集的恢复类似,只是有少许不同: 1)恢复过程需要使用完全备份集和各个增量备份集,各个备份集的恢复与前面说的一样(前滚和回滚),之后各个增量备份集的redo log都会应用到完全备份集中; 2)对于完全备机集之后产生的新表,要有特殊处理方式,以便恢复后不丢表; 3)要以完全备份集为基础,然后按顺序应用各个增量备份集。 流备份和压缩 提到流备份(streaming)就要说远程备份和备份压缩,先说流备份吧。 流备份是指备份的数据通过标准输出STDOUT传输给tar程序进行归档,而不是单纯的将数据文件保存到指定的备份目录中,参数--stream=tar表示开启流备份功能并打包。同时也可以利用流备份到远程服务器上。 举例来说, $ innobackupex --stream=TAR ${BACKUP_DIR}/base | gzip > ${BACKUP_DIR}/base.

Quagga 路由软件学习(by quqi99)

Quagga 路由软件学习(by quqi99) 作者:张华 发表于:2013-07-07 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http://blog.csdn.net/quqi99 ) Quagga是一个开源的基于Zebra实现了RIP, OSPF, BGP的动态路由软件。它提供的CLI命令和Cisco IOS类似。 1 安装 再下载源码,解压后执行下列命令: sudo yum install readline-devel #打开vty功能需要readline包 ./configure --enable-vtysh --enable-user=root --enable-group=root –enable-vty-group=root --sysconfdir=/etc/quagga –libdir=/lib make && sudo make install 如果不是用root用户,如使用quagga用户,则还需要: sudo useradd -r -d /usr/local/sbin -s /sbin/nologin quagga sudo mkdir /var/run/quagga sudo chown quagga /var/run/quagga sudo chgrp quagga /var/run/quagga 它有下列进程,根据需要启动: zebra: 路由接口声明和静态路由 bgpd: 支持BGP ospfd: 支持OSPF ospf6d: 支持IPv6 OSPF ripd: 支持RIP v2 ripngd: 支持RIP IPv6 2 配置并启动Zemba软路由 创建配置文件: sudo mv /etc/guagga/zebra.

Linux新手入门:通过chmod改变文件权限

Linux文件的三种身份和四种权限,三种身份分别为: u:文件的拥有者g:文件所属的群组o:其他用户 对于每个身份,又有四种权限,分别为: r:读取文件的权限(read)w:写入文件的权限(write)x:执行的权限(execute)s:特殊权限 在Linux文件权限详解中我们知道Linux中有两种表示文件权限的方式,分别为数字以及符号表示方式。 chmod以数字形式改变文件权限 chmod 755 test.sh 将755换算成字符形式,为rwxr-xr-x,也就是说文件的拥有者、所属群组以及其他用户都可以读取与运行test.sh这个文件,但是只有拥有者自己可以写入这个文件,也就是其他人无权修改test.sh这个文件。(当然root用户无此限制,想改谁就该谁,这也是一个体现root账号至高无上权力的体验!) 通过数学形式改变文件的权限比较简单,只要实现算好需要给文件赋予的权限,然后调用chmod指令即可,调用形式为: chmod 新的权限 文件列表 chmod以字符形式改变文件权限 chmod +x test.sh 数学形式可以一次改变文件的所有三种身份的四种权限,而字符形式则更为灵活,可以给某个身份的某个权限单独进行设置,例如上面的指令就是给三种身份都赋予执行的权限,你也可以分开单独设置: chmod u+x test.sh 只给拥有者加上可执行权限 chmod g+x test.sh 只给群组身份加上可执行权限 chmod o+x test.sh 只给其他人身份加上可执行权限 以上三条指令综合在一起等价于上面的那一条指令,都是给所有身份都开启可执行权限的功能,你也可以像下面这样来操作: chmod a+x test.sh 这里的a就代表所有的3中身份! 如果要去掉某个身份的某个权限,只需要将+变为-即可,例如去除其他人身份的可执行权限: chmod o-x test.sh 对于读取、写入等权限,按照以上方式多进行练习即可,chmod通过字符形式改变文件权限的操作见下表: chmodu g o a +(加上) -(减去) =(设定) r w x 文件或目录 最后再来个综合的示例,以后类似的问题举一反三即可: chmod u=rwx,g+rx,o-x test.sh 转载路径:http://www.letuknowit.com/topics/20120408/change-file-attributes-on-linux.html

SQL Server2005中触发器的运用

http://www.blogjava.net/qileilove/archive/2012/06/21/381239.html 编写过存储过程的人,再编写触发器时会发现:他们的语法、格式是非常类似的。其实触发器就是一种特殊类型的存储过程。他们都是预编译的,在程序正式编译前就由编译器进行编译,存储在服务器端。 不过,触发器与一般的存储过程也有些区别。触发器主要是通过对数据库的增删改的操作,或者是一个触发动作的触发作用等事件触发而被执行;而存储过程则是通过像传递SQL语句一样,传递存储过程的名字来被程序调用,实现功能。 触发器一共分为五种类型:Update触发器,Insert触发器、Delete触发器、Instead of触发器和After触发器。前三个分别是相应表上进行更新、插入、删除操作时触发。Instead of触发器在不执行插入、更新或删除操作时触发。 在触发器中存在两个虚拟表:Inserted表和Deleted表。Inserted表保存的是Insert或Update之后所影响的记录形成的表,Deleted保存的是Delete或update之前所影响的记录形成的表。这两个表是逻辑表,这两个表是动态驻留在内存中的,当触发器工作完成,这两个表也被删除。 触发器的创建代码格式: CREATE TRIGGER trigger_name --触发器的名字 ON table|view [WITH ENCRYPTION] --在哪个表上创建触发器 { FOR | AFTER | INSTEAD OF } {[INSERT][,][UPDATE][,][DELETE]} --激活触发器的类型 AS sql_statements […n] 代码中关键字for、after、Insteadof分别代表不同的使用范围: for表示为AFTER触发器,且该类型触发器仅能在表上创建; after表示只有在执行了指定的操作INSERT、DELETE、UPDATE之后触发器才被激活,执行触发器中的SQL语句; instead of当为表或视图定义了针对某一操作INSERT、DELETE、UPDATE的INSTEAD OF 类型触发器,且执行了相应的操作时,尽管触发器被触发,但相应的操作并不被执行,而运行的仅是触发器SQL语句本身。 下面说下触发器的作用: 1、级联修改数据库中的相关的表; 看下面的牛腩新闻发布系统的例子:其中一个新闻类别(Category)对应多个或者0条新闻;一条新闻(news)对应着多个或者0个新闻评论(comment)。 set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go -- ============================================= -- Author: 刘正权 -- Create date: 2008-11-15 11:13 -- Description: 删除新闻类别触发器 -- ============================================= CREATE TRIGGER trigCategoryDelete ON category instead of DELETE AS BEGIN --删除新闻,再在类别表中删除--触发器实现 declare @caId int select @caId=id from deleted --删除评论(选出多条用in,一条用=号) delete comment where newsId in (select newsId from news wherecaId=@caId) --删除新闻 delete news wherecaId=@caId --删除类别 delete category whereid=@caId END 2、执行比核查约束更为复杂的约束操作;在触发器中可以书写更为复杂的SQL语句,例如可以引用多个表,并使用if……else等语句做更复杂的检查。

ImageSource的使用心得

很多时候,我们会使用图片来装饰UI,比如作为控件背景等。 而这些图片可以分为两种形式,即存在于本地文件系统中的图片和存在于内存中的图片 对于这两种形式的图片,在WPF中,使用方法不同,下面主要说明针对这两种形式图片的使用方法 一、存在于本地文件系统中的图片文件 对于此类图片,使用非常简单,在xaml中直接指定路径即可,如: <Button> <Button.Background> <ImageBrush ImageSource="bg.jpg"/> </Button.Background> </Button> 对应的的C#代码为 ImageBrush imageBrush = new ImageBrush(); imageBrush.ImageSource = new BitmapImage(new Uri("bg.jpg", UriKind.Relative)); button.Background = imageBrush; 其中imageBrush.ImageSource的类型为ImageSource,而ImageSource是个抽象类, 因此我们不能直接使用它,而是使用它的子类来代替,查阅MSDN,可以看到它们的继承关系: System.Windows.Media.ImageSource System.Windows.Media.DrawingImage System.Windows.Media.Imaging.BitmapSource 二、存在于内存中的图片 对于只存在于内存中的图片,用以上方法就显得无能为力了,我们应该另寻他法,下面介绍一种方法: 先看代码: //此处图片从文件中读入用以模拟内存中的图片 System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap("bg.jpg"); MemoryStream stream = new MemoryStream(); bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); ImageBrush imageBrush = new ImageBrush(); ImageSourceConverter imageSourceConverter = new ImageSourceConverter(); imageBrush.ImageSource = (ImageSource)imageSourceConverter.ConvertFrom(stream); button.Background = imageBrush; 其中bitmap即是存在于内存中的Bitmap类型图片,此处使用直接加载本地图片文件模拟。 步骤是先将它保存到流中,再使用ImageSourceConverter 类的ConvertFrom方法从流中得到我们需要的图片 OK,本文到此结束,以上方法都是自己在使用中探索所得,如果有更好的方法,本人非常愿意和各位交流。 联系方式在Blog标题上

js调用COM组件示例

说明:可能需要对IE安全设置中的ActiveX控件和插件相关属性进行设置。(如果需要可以将COM组件进一步封装为ActiveX,实现ISafeObject安全接口,签名打包为EXE或CAB文件) 调用示例: function testCString() { try { var obj = newActiveXObject("atl_project.CStringModule") var str = obj.GetFilePath() alert(str) } catch (e) { alert(e.message) } }

网页在Safari快速滚动和回弹的原理: -webkit-overflow-scrolling : touch;的实现

现在很多for Mobile的HTML5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼。 要实现这个效果很简单,只需要加一行css代码即可: -webkit-overflow-scrolling : touch;可用以下网页测试: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta charset="utf-8" /> <title>scroll</title> <style type="text/css"> .container { width : 300px; height : 50%; -webkit-box-sizing : border-box; position : relative; overflow-y : auto; background-color : cyan; -webkit-overflow-scrolling : touch; /* liuhx:可以把这整行注释掉对比差别 */ } ul { height: 50px; } </style> </head> <body> <div align="center"> <nav class="container"> <ul>1</ul> <ul>2</ul> <ul>3</ul> <ul>4</ul> <ul>5</ul> <ul>6</ul> <ul>7</ul> <ul>8</ul> <ul>9</ul> <ul>10</ul> <ul>11</ul> <ul>12</ul> <ul>13</ul> <ul>14</ul> <ul>15</ul> <ul>16</ul> <ul>17</ul> <ul>18</ul> <ul>19</ul> <ul>20</ul> </nav> </div> </body> </html>可以用手指滑动中间的蓝色区域,会发现回弹效果以及滚动得很快: (点击图片查看大图)

MOV EAX,DWORD PTR SS:[EBP+8]

nasm来写可以写成 mov eax,dword ptr [ebp + 8] 理由:ebp和esp默认是ss段,所以根本不用显式说明。 eax,ebx,ecx,edx,edi,esi默认是ds段, eip默认是cs段。 补充: 上面给的是masm用法 nasm是mov eax,dword [ebp + 8] 我自己用的nasm,经常说nasm语法说习惯了。 转载于:https://www.cnblogs.com/bittorrent/p/3151706.html

02-计算字符串的实际长度(字符串处理)

StringUtil.java package com.lh.bean; public class StringUtil { // 需要计算长度的字符串 private String str; // 字符串的实际长度 private int strLength; public String getStr() { return str; } public void setStr(String str) { this.str = str; } public int getStrLength() { // 将字符串转换为字符数组 char[] c = str.toCharArray(); // 用于保存每个字符的实际长度 int factualLength = 0; for (int i = 0; i < c.length; i++) { // 获取字节数组的长度 factualLength = String.valueOf(c[i]).getBytes().length; // 当程序编码为UTF-8时,汉字实际的字节长度为3 if (factualLength == 3) { // 此处将字节长度改为2 factualLength = 2; } // 将每个字符的长度累加,结果就是字符串的总长度 strLength += factualLength; } return strLength; } public void setStrLength(int strLength) { this.

常用的正则表达式大全

常用正则表达式大全!(例如:匹配中文、匹配html) 匹配中文字符的正则表达式: [u4e00-u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[^x00-xff] 评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 匹配空白行的正则表达式:ns*r 评注:可以用来删除空白行 匹配HTML标记的正则表达式:<(S*?)[^>]*>.*?|<.*? /> 评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力 匹配首尾空白字符的正则表达式:^s*|s*$ 评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式 匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)* 评注:表单验证时很实用 匹配网址URL的正则表达式:[a-zA-z]+://[^s]* 评注:网上流传的版本功能很有限,上面这个基本可以满足需求 匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 评注:表单验证时很实用 匹配国内电话号码:d{3}-d{8}|d{4}-d{7} 评注:匹配形式如 0511-4405222 或 021-87888822 匹配腾讯QQ号:[1-9][0-9]{4,} 评注:腾讯QQ号从10000开始 匹配中国邮政编码:[1-9]d{5}(?!d) 评注:中国邮政编码为6位数字 匹配身份证:d{15}|d{18} 评注:中国的身份证为15位或18位 匹配ip地址:d+.d+.d+.d+ 评注:提取ip地址时有用 匹配特定数字: ^[1-9]d*$ //匹配正整数 ^-[1-9]d*$ //匹配负整数 ^-?[1-9]d*$ //匹配整数 ^[1-9]d*|0$ //匹配非负整数(正整数 + 0) ^-[1-9]d*|0$ //匹配非正整数(负整数 + 0) ^[1-9]d*.d*|0.d*[1-9]d*$ //匹配正浮点数 ^-([1-9]d*.d*|0.d*[1-9]d*)$ //匹配负浮点数 ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$ //匹配浮点数 ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$ //匹配非负浮点数(正浮点数 + 0) ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$ //匹配非正浮点数(负浮点数 + 0) 评注:处理大量数据时有用,具体应用时注意修正 匹配特定字符串: ^[A-Za-z]+$ //匹配由26个英文字母组成的字符串 ^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串 ^[a-z]+$ //匹配由26个英文字母的小写组成的字符串 ^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串 ^w+$ //匹配由数字、26个英文字母或者下划线组成的字符串 在使用RegularExpressionValidator验证控件时的验证功能及其验证表达式介绍如下: 只能输入数字:“^[0-9]*$” 只能输入n位的数字:“^d{n}$” 只能输入至少n位数字:“^d{n,}$” 只能输入m-n位的数字:“^d{m,n}$” 只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$” 只能输入有两位小数的正实数:“^[0-9]+(.

jsp提供了的9个内置对象

2019独角兽企业重金招聘Python工程师标准>>> 下面jsp的9大内置对象方法说明 内置对象 类型 作用域 request javax.servlet.http.HttpServletRequest request response javax.servlet.http.HttpServletResponse response pageContext javax.servlet.jsp.PageContext page session javax.servlet.http.HtpSession session application javax.servlet.jsp.ServletContext application out javax.servlet.jsp.JspWriter page config javax.servlet.ServletConfig page page java.lang.Object page exception java.lang.Throwable page 根据它们的作用进行分类 : 第一类:与Servlet有关:page和config 第二类:与Input/Output有关:out,request和response 第三类:与Context有关:application,session和pageContext 第四类:与Error有关:exceptio 对象作用范围 : 1、page:就是设置的属性只能在当前页面有效。通过pageContext的setAttribute()和getAttribute()。 2、request:指属性在一次请求范围内有效。如果页面从给一个页面跳转到另一个页面,那么该属性就失效了。这里所指的跳转是指客户端跳转,比如客户单击超链接跳转到其他页面或者通过浏览器地址栏浏览其他页面。如果使用服务器端跳转<jsp:forward>,则该属性仍然生效。同理使用request对象的setAttribute()和getAttribute()。 3、session:指客户浏览器与服务器一次会话范围内,如果服务器断开连接,那么属性就失效了。同理通过session对象的setAttribute()和getAttribute()。session范围的例外比如重新打开一个浏览器。 4、application:指在整个服务器范围,知道服务器停止以后才会失效。同理通过application对象的setAttribute()和getAttribute()。application范围就是保存的属性只要服务器不重启,就能在任意页面中获取,就算重新打开浏览器也是可以获取属性的。 9大对象方法说明 : 1.request对象 客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求, 然后做出响应。它是HttpServletRequest类的实例。 objectgetAttribute(Stringname) 返回指定属性的属性值 EnumerationgetAttributeNames() 返回所有可用属性名的枚举 StringgetCharacterEncoding() 返回字符编码方式 intgetContentLength() 返回请求体的长度(以字节数) StringgetContentType() 得到请求体的MIME类型 ServletInputStreamgetInputStream() 得到请求体中一行的二进制流 StringgetParameter(Stringname) 返回name指定参数的参数值 EnumerationgetParameterNames() 返回可用参数名的枚举 String[]getParameterValues(Stringname) 返回包含参数name的所有值的数组 StringgetProtocol() 返回请求用的协议类型及版本号 StringgetScheme() 返回请求用的计划名,如:http.

ContactContract部分重要点翻译

转载请注明出处:http://blog.csdn.net/droyon/article/details/9088547 /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "

poj 怪盗基德的滑翔翼

2019独角兽企业重金招聘Python工程师标准>>> /** F:怪盗基德的滑翔翼查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为目标的超级盗窃犯。而他最为突出的地方,就是他每次都能逃脱中村警部的重重围堵,而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼。 有一天,怪盗基德像往常一样偷走了一颗珍贵的钻石,不料却被柯南小朋友识破了伪装,而他的滑翔翼的动力装置也被柯南踢出的足球破坏了。不得已,怪盗基德只能操作受损的滑翔翼逃脱。 假设城市中一共有N幢建筑排成一条线,每幢建筑的高度各不相同。初始时,怪盗基德可以在任何一幢建筑的顶端。他可以选择一个方向逃跑,但是不能中途改变方向(因为中森警部会在后面追击)。因为滑翔翼动力装置受损,他只能往下滑行(即:只能从较高的建筑滑翔到较低的建筑)。他希望尽可能多地经过不同建筑的顶部,这样可以减缓下降时的冲击力,减少受伤的可能性。请问,他最多可以经过多少幢不同建筑的顶部(包含初始时的建筑)? 输入 输入数据第一行是一个整数K(K < 100),代表有K组测试数据。 每组测试数据包含两行:第一行是一个整数N(N < 100),代表有N幢建筑。第二行包含N个不同的整数,每一个对应一幢建筑的高度h(0 < h < 10000),按照建筑的排列顺序给出。 输出 对于每一组测试数据,输出一行,包含一个整数,代表怪盗基德最多可以经过的建筑数量。 样例输入 3 8 300 207 155 299 298 170 158 65 8 65 158 170 298 299 155 207 300 10 2 1 3 4 5 6 7 8 9 10样例输出 6 6 9 */ #include <cstdio> #include <list> using namespace std; int main() { int k = 0; scanf("

Adaptively biased MD,steered MD, and umbrella sampling with REMD

Adaptively Biased Molecular Dynamics (ABMD) Reaction Coordinates variable 部分用于定义反应的坐标,这部分必须包含一个关键字"type",以及一个STRING值,以及一系列的整数(整数的数量取决于变量的类型),对于一些反应坐标的类型, Variable部分的必须包含一系列的实数值,r, r的长度取决于具体的类型。 现在可以应用下面的反应坐标: type=DISTANCE : 定义两个原子之间的坐标,原子的索引从列表 i 中读取. type=LCOD : linear combination of distances (in A).从r的列表中读取原子的坐标. 例如:i=(1,2,3,4) 和 r=(1.0,-1.0)定义原子1和原子2之间的距离, 原子3和原子4之间的距离. type=ANGLE : 用于指定i1,i2和i2,i3之间的角度(以弧度的方式表示) type=TORSION :用于指定i1,i2,i3,i4之间形成的二面角(以弧度的方式表示). type=COS_OF_DIHEDRAL : 用于指定list i 中指定的所有的二面角的cosine值的总和. 原子的总数必须是四的倍数. type=R_OF_GYRATION : 列表i中指定的原子的回转半径(in A) type=MULTI_RMSD :几个groups的RMSD (in A),i 列出了一系列的原子,这些group之间以0分割, 上图中定义了两个group,第一个group由四个原子1,2,3,4组成(i中第一个0之前定义的四个原子),第二个group定义了3个原子(3,4,5). 首先计算第一个group的RMSD的值(R1),然后计算第二个group的RMSD值(R2),最后将计算变量的值: M1和M2分别为对应的group1和group2中的原子的原子量的总值. type=N_OF_BONDS: Steered Molecule Dynamics (SMD) 如果在mdin文件中指定了ncsu_smd部分,除了variable部分指定的参数外,ncsu_smd中还可以指定另外的一些的参数. output_file=STRING : 设置输出文件的名称 output_freq=INTEGER ; 设置输出的频率。(in MD steps) 下面是一个例子: 反应坐标为第5个和第9个原子之间的距离,第14行定义了距离的弹性常数,这个常数在MD中保持不变,第13行定义了steering path(字母X指定了在MD开始的时候使用的变量的值)。每50步将值输入到smd.txt文件中.

【转】JavaScript与Java的区别

原文地址:http://www.qeefee.com/js/difference-between-javascript-and-java 更多Javascript教程,欢迎访问起飞网>>Javascript教程 正文: 关于java和javascript的关系,我曾在一个论坛上看过这样一句话,java和javascript的关系,就好比雷锋和雷峰塔的关系,实在是经典! 因为名字的关系,总是有人误以为Javascript是Java的一个子集,或者必然会存在一些关系。但非常让大家失望,这两种编程语言除了名字开头相同之外,没有其它内在的关系! 什么是Javascript? 我在上一篇Javascript简介中已经介绍了什么是Javascript,它是运行在浏览器中的一种脚本语言,在web页面中,Javascript可谓是无所不能: 可以操作HTML,提供了一种运行时改变HTML的工具可以附加并执行事件,符合面向事件编程的思想数据验证功能,在提交表单时对表单数据进行合法性验证对客户浏览器的操作,前进、后退、刷新、跳转、打开新窗口、打印等可以创建并使用Cookies 什么是Java呢? Java是Sun公司推出的一种编程语言。它是一种通过解释方式来执行的语言,语法规则和C++类似。同时,Java也是一种跨平台的程序设计语言。用Java语言编写的程序叫做“Applet”(小应用程序),用编译器将它编译成类文件后,将它存在WWW页面中,并在HTML档上作好相应标记,用户端只要装上Java的客户软件就可以在网上直接运行“Applet”。 Java非常适合于企业网络和Internet环境,现在已成为Internet中最受欢迎、最有影响的编程语言之一。 Java有许多值得称道的优点,如简单、面向对象、分布式、解释性、可靠、安全、结构中立性、可移植性、高性能、多线程、动态性等。Java摈弃了C++中各种弊大于利的功能和许多很少用到的功能。 Jave可以运行与任何微处理器,用Java开发的程序可以在网络上传输,并运行于任何客户机上。 Javascript名字的由来 JavaScript最早是被称为Mocha(魔卡)的,这是这个项目的代码名。这个名字一直用到Netscape2.0 beta 2发布之前(95.11.04)——包括在beta 1中弹出的错误框上,还可以看到Mocha的名字。不过,早在此前的9月18号,netscape就已经发布消息将在LiveWire中启用一种服务器端脚本(未提及名称)。又因为我们前面提到的“前后端通用脚本”的设计,该语言在beta 2发布时就使用了内部名称LiveScript。 但同样混乱的事情是,事实上这时Netscape已经决定将该语言命名为“JavaScript”。因此在beta 2的发布备忘中该语言称为JavaScript,而界面上却从Mocha改为了LiveScript。这一局面一直持续到12月4日,netscape与sun共同发布声明,正式启用了JavaScript这个名字。随后beta 4发布(95.12.20),界面和文档上就统一了。 所以事实上“LiveScript”这个名字可以考证的生命周期,也就只有一个月的时间(在95.11.04- 12.04)。但Mocha毕竟只是项目代码名,而非产品名,所以后来人们追溯JavaScript的历史,大多只提到LiveScript为止。 Javascript和Java的区别 一、javascript与Java是由不同的公司开发的不同产品。javascript是Netscape公司的产品,其目的是为了扩展Netscape Navigator功能,而开发的一种可以嵌入Web页面中的基于对象和事件驱动的解释性语言;而Java是SUN Microsystems公司推出的新一代面向对象的程序设计语言,特别适合于Internet应用程序开发。实际上,javascript最初的名字并不是javascript,而是LiveScript,名字中的“Java”是经过SUN Microsystems公司授权的。 二、javascript是基于对象的,它是一种脚本语言,是一种基于对象和事件驱动的编程语言,因而它本身提供了非常丰富的内部对象供设计人员使用。而Java是面向对象的,即Java是一种真正的面向对象的语言,即使是开发简单的程序也必须设计对象。 三、javascript与Java嵌入方式不一样。在HTML文档中,两种编程语言的标识不同,javascript使用<script></script>来标识,而Java使用Applet来标识。 四、javascript与Java在浏览器中所执行的方式不一样。javascript是一种解释性编程语言,其源代码在发往客户端执行之前不需经过编译,而是将文本格式的字符代码发送给客户,即javascript语句本身随Web页面一起下载下来,由浏览器解释执行。而Java的源代码在传递到客户端执行之前,必须经过编译,因而客户端上必须具有相应平台上的仿真器或解释器,它可以通过编译器或解释器实现独立于某个特定的平台编译代码。 五、javascript与Java代码格式不一样。javascript的代码是一种谋咀址格式,可以直接嵌入HTML文档中,并且可动态装载,编写HTML文档就像编辑文本文件一样方便,其独立文件的格式为*.js。Java是一种与HTML无关的格式,必须通过像HTML中引用外媒体那么进行装载,其代码以字节代码的形式保存在独立的文档中,其独立文件的格式为*.class。 六、javascript与Java所采取的变量是不一样的。javascript中的变量声明采用弱类型,即变量在使用前不需作声明,而是解释器在运行时检查其数据类型。Java采用强类型变量检查,即所有变量在编译之前必须作声明。 七、javascript采用动态联编,即javascript的对象引用在运行时进行检查。Java采用静态联编,即Java的对象引用必须在编译时的进行,以使编译器能够实现强类型检查。 八、javascript不直接对文本和图形进行操作,它在Web页面中与HTML元素组合一起发挥作用,但它可以控制浏览器,让浏览器直接对文本和图形进行处理。而Java则可以直接对文本和图形进行操作。 转载于:https://www.cnblogs.com/youring2/archive/2013/06/06/3120645.html

sql distinct 关键字失效的办法

用distinct关键字只能过滤查询字段中所有记录相同的(记录集相同),而如果要指定一个字段却没有效果,另外distinct关键字会排序,效率很低。selectdistinctnamefromt1能消除重复记录,但只能取一个字段,现在要同时取id,name这2个字段的值。sel 用distinct关键字只能过滤查询字段中所有记录相同的(记录集相同),而如果要指定一个字段却没有效果,另外distinct关键字会排序,效率很低。 selectdistinctnamefromt1能消除重复记录,但只能取一个字段,现在要同时取id,name这2个字段的值。 selectdistinctid,namefromt1可以取多个字段,但只能消除这2个字段值全部相同的记录 所以用distinct达不到想要的效果,用groupby可以解决这个问题。 例如要显示的字段为A、B、C三个,而A字段的内容不能重复可以用下面的语句: selectA,min(B),min(C),count(*)from[table]where[条件]groupbyA having[条件]orderbyAdesc 为了显示标题头好看点可以把selectA,min(B),min(C),count(*)换称selectAasA,min(B)asB,min(C)asC,count(*)as重复次数 显示出来的字段和排序字段都要包括在groupby中 但显示出来的字段包有min,max,count,avg,sum等聚合函数时可以不在groupby中 如上句的min(B),min(C),count(*) 一般条件写在where后面 有聚合函数的条件写在having后面 如果在上句中having加count(*)>1就可以查出记录A的重复次数大于1的记录 如果在上句中having加count(*)>2就可以查出记录A的重复次数大于2的记录 如果在上句中having加count(*)>=1就可以查出所有的记录,但重复的只显示一条,并且后面有显示重复的次数----这就是所需要的结果,而且语句可以通过hibernate 下面语句可以查询出那些数据是重复的: select字段1,字段2,count(*)from表名groupby字段1,字段2havingcount(*)>1 将上面的>号改为=号就可以查询出没有重复的数据了。 例如selectcount(*)from(selectgcmc,gkrq,count(*)fromgczbxx_zhaotgroupbygcmc,gkrqhaving count(*)>=1orderbyGKRQ) 推荐使用: select*fromgczbxx_zhaowhereviewidin(selectmax(viewid)fromgczbxx_zhaogroupby gcmc)orderbygkrqdesc ps:distinct distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数, 而不是用它来返回不重记录的所有值。 其原因是distinct只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。 下面先来看看例子: table表 字段1字段2 idname 1a 2b 3c 4c 5b 库结构大概这样,这只是一个简单的例子,实际情况会复杂得多。 比如我想用一条语句查询得到name不重复的所有数据,那就必须使用distinct去掉多余的重复记录。 selectdistinctnamefromtable 得到的结果是: ---------- name a b c 好像达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧: selectdistinctname,idfromtable 结果会是: ---------- idname 1a 2b 3c 4c 5b distinct怎么没起作用?作用是起了的,不过他同时作用了两个字段,也就是必须得id与name都相同的才会被排除。。。。。。。 我们再改改查询语句: selectid,distinctnamefromtable 很遗憾,除了错误信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,照样报错。 ------------------------------------------------------------------------------------------------------------ 下面方法可行: select*,count(distinctname)fromtablegroupbyname 结果: idnamecount(distinctname) 1a1 2b1 3c1

正确使用Block避免Cycle Retain和Crash

Block简介 Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事。需要注意的是由于Objective-C在iOS中不支持GC机制,使用Block必须自己管理内存,而内存管理正是使用Block坑最多的地方,错误的内存管理 要么导致return cycle内存泄漏要么内存被提前释放导致crash。 Block的使用很像函数指针,不过与函数最大的不同是:Block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,Block不仅 实现函数的功能,还能携带函数的执行环境。 可以这样理解,Block其实包含两个部分内容 Block执行的代码,这是在编译的时候已经生成好的; 一个包含Block执行时需要的所有外部变量值的数据结构。 Block将使用到的、作用域附近到的变量的值建立一份快照拷贝到栈上。 Block与函数另一个不同是,Block类似ObjC的对象,可以使用自动释放池管理内存(但Block并不完全等同于ObjC对象,后面将详细说明)。 Block基本语法 1 2 3 4 5 6 7 8 9 10 11 // 声明一个Block变量 long (^sum) (int, int) = nil; // sum是个Block变量,该Block类型有两个int型参数,返回类型是long。 // 定义Block并赋给变量sum sum = ^ long (int a, int b) { return a + b; }; // 调用Block: long s = sum(1, 2); 定义一个实例函数,该函数返回Block: 1 2 3 4 5 6 7 8 9 - (long (^)(int, int) sumBlock { int base = 100; return [[ ^ long (int a, int b) { return base + a + b; } copy] autorelease]; } // 调用Block [self sumBlock](1,2); 是不是感觉很怪?为了看的舒服,我们把Block类型typedef一下

汇编反汇编

Linux与windows汇编的区别 Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数,而Windows下却是相反。 基本操作指令 操作数类型: 1. 立即数操作数,也就是常数值。立即数的书写方式是“$”后面跟一个整数,比如$0x1F,这个会在后面的具体分析中见到很多。 2. 寄存器操作数,它表示某个寄存器的内容,用符号Ea来表示任意寄存器a,用引用R[Ea]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器表示符作为索引。 3. 操作数是存储器引用,它会根据计算出来的地址(通常称为有效地址)访问某个存储器位置。用符号Mb[Addr]表示对存储在存储器中从地址Addr开始的b字节值的引用。通常可以省略下标b。 下面表格表示多种不同的寻址模式: 操作数类型 格式 操作数值 名称 立即数 $Imm Imm 立即数寻址 寄存器 Ea R[Ea] 寄存器寻址 寄存器 Imm M[Imm] 绝对寻址 寄存器 (Ea) M[R[Ea]] 间接寻址 寄存器 Imm(Eb) M[Imm+R[Eb]] (基址+偏移量)寻址 寄存器 (Eb,Ei) M[R[Eb]+R[Ei]] 变址寻址 寄存器 M[Imm+R[Eb]+R[Ei]] 寄存器 (,Ei, s) M[R[Ei] * s] 伸缩化的变址寻址 寄存器 Imm(,Ei, s) M[Imm+R[Ei] * s]] 伸缩化的变址寻址 寄存器 (Eb,Ei, s) M[R[Eb]+R[Ei] * s] 伸缩化的变址寻址 寄存器 Imm(Eb,Ei, s) M[Imm+R[Eb]+R[Ei] * s] 伸缩化的变址寻址

解决MySQL错误reading initial communication packet_MySQL的两种方法

解决MySQL错误reading initial communication packet_MySQL的两种方法 打开MYSQL的时候提示reading initial communication packet, 而且网站访问出现如题reading initial communication packet(2013)错误, 处理方法一: 查找MYSQL配置文件: 检查my.cnf,发现innodb_buffer_pool_size = 18M 设置过小,调整为innodb_buffer_pool_size = 1024M即可,网上介绍是过大处理其他解决方法,解决我的问题。 Lost connection to MySQL server at 'reading initial communication packet' 错误解决 如果还不能处理问题则采用下面方法; 1、修改mysql配置文件 vi /etc/my.cnf [mysqld]段加skip-name-resolve 在这个之前要把mysql的远程访问权限打开,或者再加skip-grant-table(不推荐) 2、修改hosts.allow vi /etc/hosts.allow 加mysqld : ALL : ALLOW mysqld-max : ALL :ALLOW 这一次搞定!

SIM卡ICCID标识与IMSI的区别

ICCID:Integrate circuit card identity 集成电路卡识别码(固化在手机SIM卡中) ICCID为IC卡的唯一识别号码,共有20位数字组成。 IMSI: International Mobile SubscriberIdentification Number 国际移动用户识别码,是区别移动用户的标志,储存在SIM卡中,可用于区别移动用户的有效信息。其总长度不超过15位,同样使用0~9的数字。其中MCC是移动用户所属国家代号,占3位数字,中国的MCC规定为460;MNC是移动网号码,最多由两位数字组成,用于识别移动用户所归属的移动通信网;MSIN是移动用户识别码,用以识别某一移动通信网中的移动用户。例如开头是46000是中国移动用户,46001是联通用户,46003是电信用户 一张SIM卡,里面有ICCID,也有IMSI。 ICCID是卡的标识,IMSI是用户的标识。 ICCID只是用来区别SIM卡,不作接入网络的鉴权认证。而IMSI在接入网络的时候,会到运营商的服务器中进行验证。 ICCID可以伪造,可以用一张空白多号卡,写入IMSI和KI,只要是经过破解的IMSI和KI,就可以接入网络,而ICCID可以任意20位数字。 iPhone手机在激活的时候,会把ICCID和IMSI一起发送到苹果服务器端进行验证。特别是有锁的手机,就使用IMSI来判断是否合法运营商,如果不合法,就无法激活。ICCID作为SIM卡标识,在激活的时候被记录下来,直到下次刷机,在服务端的记录都不会被改变。 以下是iPhone激活时发送到苹果服务器的部分验证数据 IntegratedCircuitCardIdentity 89011200000056767*** InternationalMobileEquipmentIdentity 990002252729*** InternationalMobileSubscriberIdentity 310120005676*** MobileEquipmentIdentifier 99000225272***

H3C 登陆用户及权限

1、设定本地用户名、密码、登陆模式telnet,权限3(此用户名+密码可以用来web及telnet) local-user admin password cipher $c$3$kIczSmT80P7fN18cDb46i8Yjddo8ggF2OPs= service-type telnet level 3 2、设定telnet登陆验证模式为scheme user-interface vty 0 4 authentication-mode scheme 有这个设定则上述用户名+密码无法telnet: domain system scheme radius-scheme system

Send函数和Recv函数解析

下文摘自gogor的博客http://blog.csdn.net/gogor/article/details/5896931 Send函数和Recv函数解析 1. send函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户端还是服务器端应用程序都用send函数来向TCP连接的另一端发送数据。 客户端程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。 该函数的: 第一个参数指定发送端套接字描述符; 第二个参数指明一个存放应用程序要发送数据的缓冲区; 第三个参数指明实际要发送的数据的字节数; 第四个参数一般置0。 这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议 是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余 空间大小send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。 要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在执 行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回 SOCKET_ERROR) 注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。 Send函数的返回值有三类: (1)返回值=0: (2)返回值<0:发送失败,错误原因存于全局变量errno中 (3)返回值>0:表示发送的字节数(实际上是拷贝到发送缓冲中的字节数) 错误代码: EBADF 参数s 非合法的socket处理代码。 EFAULT 参数中有一指针指向无法存取的内存空间 ENOTSOCK 参数s为一文件描述词,非socket。 EINTR 被信号所中断。 EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 2. recv函数 int recv( SOCKET s, char FAR *buf, int len, int flags ); 不论是客户端还是服务器端应用程序都用recv函数从TCP连接的另一端接收数据。

ios打包IPA的各种问题和解决方法

最近做了一个东西,在打包ipa文件时遇到了各种问题,纠结了我好几天。 由于我一直是做android的,在打包时以为ios打包也和android一样:用IDE(eclipse)生成一个签名证书,然后打包。事实证明ios的打包比这复杂多了。下面介绍一下我遇到的各种问题。 1.证书问题 要打包ipa首先需要设置code sign identity,一个应用需要打包至少需要三个要素:证书,APP ID,还有一个容易被忽略的provisioning profile。 证书的申请流程到处都可以找到,这里只简单介绍一下,首先使用钥匙串创建一个certSigningRequest文件,然后登录apple developer的ios developer申请证书,将certSigningRequest文件上传,生成一个证书,将它下载下来即可。 接着是APP ID,仍然是到apple developer创建,一般是公司域名的倒写加应用名。 我之前一直以为到这里就结束了,就archive,结果每次都悲剧。问题出在provisioning profile上,之前一直不理解为什么要这个东西,当我创建之后就知道它存在的理由了。大家知道应用在发布之前,要在没有越狱的真机上测试的话,就要将机器UDID添加到你的开发者帐号中去,而一个应用如何知道你的开发者帐号里面添加了哪些UDID呢?就是通过provisioning profile,它也是通过apple developer官网创建,在创建时会让你选择类型,打包ipa测试的话就选择AD HOC,记得添加UDID,创建后下载下来生成mobileprovision文件,双击运行即添加到资源库中去,而xcode在读取你的系统里的证书时实际上是在查找资源库里面的provisioning profile。provisioning profile包含了证书,APP ID和UDID列表,archive后这些信息会被加入ipa中。 2."file not found" 在archive时会碰到一个蛋疼的问题,就是明明在模拟器编译运行都正常,但是打包ipa时却报一个找不到头文件的错,这是由于直接编译时使用的是你的系统的头文件目录,而archive时使用的时SDK下的头文件目录,一般情况下这两者时一致的,但是有些特殊库的头文件,如libxml,在系统下/usr/include/libxml2是包含在头文件自动搜索范围内的,而SDK中这个目录不在自动搜索范围内,所以就会报一个"file not found"。 解决方式就是在编译参数里面添加一个头文件搜索目录,工程->build setting,搜索header search paths,添加你需要手动添加的头文件目录,如/usr/include/libxml2。 3.显示archive success,但是organizer不能自动弹出,手动打开也看不到刚刚打的包,或者没有share按钮可点 在介绍这个问题之前,我首先要吐糟一下某水果公司,这个问题足足浪费了我一个下午的时间,本来我可以不用加班的,当解决之后我恨不得跑到米国把某水果公司给炸了。 遇到这种问题可能有各种不同的原因,但是我敢说90%以上都是因为同一个原因,而这个问题的解决方法也超简单,工程->build setting,搜索deployment,找到skip install项,将其改成NO,target->build setting,搜索deployment,找到skip install项,将其改成NO,网上找到一些资料说target下要改成YES,但是我真实操作下却是改成NO才生成ipa的,说实话,我并不理解它的原理,各位看官可以YES和NO都试一下。 目前遇到的比较头疼的问题就这三个,以后遇到新的再更新。

MSSQL2005 登录名、角色、数据库用户、角色、架构的关系

http://hi.baidu.com/theonote/item/2e9c4af70b14c25f932af2ce MS-SQL2005服务器登录名、角色、数据库用户、角色、架构的关系 今天要说的包括服务器登录名Server Login,服务器角色Server Role,数据库用户DB User,数据库架构DB Schema,数据库角色DB Role 。以上几个名词应该从服务器与数据库来区分,服务器包含一到多个数据库,其中: 服务器登录名,指有权限登录到某服务器的用户; 服务器角色,指一组固定的服务器用户,默认有9组; 登录名一定属于某些角色,默认为public 服务器角色不容许更改 登录后也不一定有权限操作数据库 数据库用户,指有权限能操作数据库的用户; 数据库角色,指一组固定的有某些权限的数据库角色; 数据库架构,指数据库对象的容器; 数据库用户对应于服务器登录名以便登录者可以操作数据库 数据库角色可以添加,可以定制不同权限 数据库架构,类似于数据库对象的命名空间,用户通过架构访问数据库对 服务器登录名属于某组服务器角色; 服务器登录名需要于数据库的用户映射后才拥有操作数据库的权限 数据库用户属于某组数据库角色以获取操作数据库的权限 数据库角色拥有对应的数据库架构,数据库用户可以通过角色直接拥有架构 数据库用户有默认架构,写SQL语句可以直接以“对象名”访问 非默认架构则要以“架构名.对象名”访问 因此,新建一个非SA账户并建立数据库的过程可以如下: 1、新建登录名Login1 2、新建数据库DB1 3、新建DB1的架构Schema1 4、新建BD1的用户User1,登录名对应Login1,默认架构选择Schema1,角色选择db_owner 5、在登录名Login1的属性窗口里选择“用户映射”,勾选DB1,在用户里填写User1,默认架构选择"Schema1" 6、至此,新建表名会是Schema1.Table1,其他对象也如此 7、当然还可以新建其他架构的对象Schema2,只有User1拥有该架构,一样可以访问,如Schema2.Table2 值得注意的是,当为登录映射数据库用户的时候,多个数据库可以有相同名称的用户,而单独为某个数据库新建的用户,如User1,则在其他数据库里不允许同名。 以上就是全文,希望对大家理解并创建数据库有些帮助,也请大家多多交流。

android -- 蓝牙 bluetooth (一) 入门

前段时间在 网上看了一些关于android蓝牙的文章,发现大部分是基于老版本(4.1以前含4.1)的源码,虽然无碍了解蓝牙的基本原理和工作流程,但对着4.2.2的代码看起来总是有些遗憾。所以针对4.2.2版本代码整理下相关知识,当然蓝牙工作的主干流程是没有变的,上电、加载驱动这些动作少不了的,只是这些功能的实现代码位置变了不少。希望本文可以让大家对android4.2的蓝牙部分代码有一个初步的了解。 正文开始前,先明确代码版本:android jellyBean 4.2.2,后续的蓝牙相关文章同样如此。 另推荐个源码在线阅读网址 http://androidxref.com/,已经知道的童鞋无视这行吧。 入手一个新的模块或应用,当然首先要知道它都有什么了,与它相关的代码在那里,所以先一起看下蓝牙代码分布吧。 1. 代码分布: packages/apps/Bluetooth/ 看这路径肯定是蓝牙应用方面的代码了,主要是关于蓝牙应用协议的表现代码,包括opp、hfp、hdp、a2dp、pan等等,这些名词后面再解释。 frameworks/base/core/java/android/server/ 4.2以后这个目录虽然还有了,但里面代码已经转移到应用层了,就是前面那个目录,所以4.2.2上的蓝牙这里可以忽略。 framework/base/core/java/android/bluetooth 这个目录里的代码更像一个桥梁,里面有供java层使用一些类,也有对应的aidl文件联系C、C++部分的代码,还是挺重要的。 kernel\drivers\bluetoothBluetooth 具体协议实现。包括hci,hid,rfcomm,sco,SDP等协议 kernel\net\bluetooth Linux kernel 对各种接口的Bluetoothdevice的驱动。例如:USB接口,串口等,上面kernel这两个目录有可能看不到的,但一定会有的。 external\bluetooth\bluedroid BlueZ (应用空间协议),官方蓝牙协议栈。 system\bluetoothBluetooth 适配层代码,和framework那个作用类似,是串联framework与blueZ的工具。 大致代码分布就是这些,初步查看后让我们再来看下蓝牙的整体结构。 2.整体结构: 这部分直接上图了,看着直观些。图中把JNI部分虽然在目前4.2的代码中在packages层,这里还是画在Framework层了,说明下希望 不要引起理解的误会。从图上可以感觉到整体流程和以前变化不大,所以流程方面的文章看4.1或更早的应该问题也不大。 PS:上图关于蓝牙协议栈的说明有误,4.2里已经不再是bluez了,在些更正一下,当然协议栈这一部分还是要有的,新的协议栈看下面英文: Android 4.2 introduces a new Bluetooth stack optimized for use with Android devices. The new Bluetooth stack developed in collaboration between Google and Broadcom replaces the stack based on BlueZ and provides improved compatibility and reliability. google和broadcom合作开发了一个新蓝牙协议栈,老版本的兼容性问题在所难免了。在此感谢网友andger032的提醒。

Class.forName() 理解

在网上查了一下有关Class.forName(”X”)的资料,很多人都不理解数据库连接为什么要用到这个,自己做了一下总结。 Class.forName(“X”)返回与带有给定字符串名的类或接口相关联的Class对象。 调用此方法等效于: Class.forName(className, true, currentLoader) 参数: name - 所需类的完全限定名 initialize - 是否必须初始化类 currentLoader - 用于加载类的类加载器 调用forName(“X”)将导致命名为X的类被初始化。 Class.forName(“X”)与 ClassLoader cl = Thread.currentThread().getContextClassLoader(); Class clazz = cl.loadClass("X"); 的区别在于类是否被初始化。 只有执行clazz.newInstance();时才能够初始化类。 newInstance():创建此Class对象所表示的类的一个新实例。 看一下JDBC驱动的装载。 Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbcurl"); 当调用Class.forName("com.mysql.jdbc.Driver");是Driver已经被初始化并注册到DriverManager中。 看一下MySQL Driver的代码: public class Driver extends NonRegisteringDriver implements java.sql.Driver { public Driver() throws SQLException { } static { try { DriverManager.registerDriver(new Driver()); } catch(SQLException E) { throw new RuntimeException("Can't register driver!"); } } } 改修JDBC驱动的装载

编译iOS上的libevent库

前言:昨天正好在Android上把libevent跑通了,就是用了之前一篇文章中提到的流程方案。今天索性把iOS上的libevent也编译了下。iOS上的交叉编译比NDK的要顺利许多,大概是找到了对应比较好的文章做参考吧。 准备工作 有OS X系统,我这里装的是10.8 64-bit。 Xcode是4.5.2,对应的SDK版本为6.0 下载libevent版本,可是是官方最新的2.0.21或者是git上对应的那个for Android的版本,都可以。git上那份我记得是2.0.20的,差距应该不大。 下载openssl库,目前最新是1.0.1e的版本 编译 生成configure文件 如果是官方的2.0.21-stable版本,则文件中已经有configure文件生成了,这步骤可以跳过。如果没有,则执行目录下的autogen.sh脚本,生成configure。其间可能需要安装autoconf、automake和libtool等工具,直接下载对应的源码,然后编译安装即可。至于如何安装,我给个命令列表,有需要的看下即可: ./configure && make sudo make install 经过以上的步骤,libevent源码目录下应该已经有configure等文件生成了。 编辑build_libevent.sh脚本 接下来就是编写编译脚本了,实际上就是使用configure工具,指定对应的生成目录。这里可以给一个洋葱浏览器的开源脚本,很强大,帮你直接在MAC OS X上下载编译libevent库。 https://github.com/mtigas/iOS-OnionBrowser/blob/master/build-libevent.sh 我的配置基本都是抄里面的,当然,如果直接用也没什么问题,他会帮你下载libevent和openssl库,然后编译,生成对应的静态库文件。值得一提的是,Mac上可以直接用lipo命令把多份静态库整合到一起,比如i386、armv7和armv7s三种CPU架构的静态库整合成一份,这实在让人很兴奋。如果Android上也能这么搞,那该多好,当然我还没去查阅过资料,不知道linux上是否支持lipo。 编译libevent的库有个要注意的地方(这个坑了我很久),就是如果需要openssl支持,那要先编译openssl库,否则是不会带libevent_openssl.a这个静态库的。 下面我索性把那两个bash脚本放上来,首先是libevent的 #!/bin/bash # Builds libevent for all three current iPhone targets: iPhoneSimulator-i386, # iPhoneOS-armv6, iPhoneOS-armv7. # # Copyright 2012 Mike Tigas <mike@tig.as> # # Based on work by Felix Schulze on 16.12.10. # Copyright 2010 Felix Schulze. All rights reserved. # # Licensed under the Apache License, Version 2.

SQL集合操作符的用法(Oracle中)

集合操作符:将两个查询的结果组合成一个结果集。 在Oracle中有两张表 表A no 表B no 1 1 2 4 3 1. UNION(联合) UNION操作符返回两个查询选定的所有不重复的行。 SQL> SELECT no FROM A UNION SELECT no FROM B; 结果: no 1 2 3 4 2. UNION ALL(联合所有) 合并两个查询选定的所有行,包括重复的行。 上面SQL语句,把 UNION 改为 UNION ALL 结果: no 1 2 3 1 4 3. INTERSECT(交集) 返回两个查询都有的行。 上面SQL语句,把 UNION 改为 INTERSECT 结果: no 1 4. MINUS(减集) 返回第一个查询选定但是没有被第二个查询选定的行。 上面SQL语句,把 UNION 改为 MINUS 结果: no 2 3 ====================================================== 集合操作有 并,交,差 3种运算。 union :得到两个查询结果的并集,并且自动去掉重复行。不会排序 union all:得到两个查询结果的并集,不会去掉重复行。也不会排序 intersect:得到两个查询结果的交集,并且按照结果集的第一个列进行排序 minus:得到两个查询结果的减集,以第一列进行排序 例子: 下面是两个表:一个主修课程表,一个选修课程表。 这个是主修课程表:minors create table minors( minor_id number primary key, minor_name varchar2(30) not null, credit_hour number(2) ) 插入3条记录: insert into minors values(10101,'计算机原理',4) insert into minors values(10201,'自动控制原理',3) insert into minors values(10301,'工程制图原理',4) 下面创建选修课程表minors2 create table minors2( minor_id number primary key, minor_name varchar2(30) not null, credit_hour number(2) ) 插入两条记录: insert into minors2 values(10201,'自动控制原理',3) insert into minors2 values(10301,'工程制图原理',4) (1)

lz4: 性能很好的压缩算法

原创翻译文章,转载请注明出处http://blog.csdn.net/erlib 作者Sunface 最近在不少项目特别是存储相关的项目用到了lz4压缩算法,它有什么特点呢? LZ4 is a very fast lossless compression algorithm, providing compression speed at 300 MB/s per core, scalable with multi-cores CPU. It also features an extremely fast decoder, with speeds up and beyond 1GB/s per core, typically reaching RAM speed limits on multi-core systems. 这个特性对于需要大吞吐量的压缩场合还是非常有用的,以很小的CPU代价换来更大的存储密度。 官方网站:https://code.google.com/p/lz4/, 摘抄下它的性能指标: Name Ratio C.speed D.speed LZ4 (r59) 2.084 330 915 LZO 2.05 1x_1 2.038 311 480 QuickLZ 1.5 -1 2.233 257 277

linux编程 select函数说明

文章出处:http://www.cnblogs.com/zhuyp1015/archive/2012/05/31/2529079.html 首先再来提一下I/O多路转接的基本思想:先构造一张有关描述符的表,然后调用一个函数,它要到这些描述符中的一个已准备好进行 I/O时才返回。在返回时,它告诉进程哪一个描述符已准备好可以进行 I/O。 select函数的参数将告诉内核: (1) 我们所关心的描述符。 (2) 对于每个描述符我们所关心的条件(是否读一个给定的描述符?是否想写一个给定的 描述符?是否关心一个描述符的异常条件?)。 (3) 希望等待多长时间(可以永远等待,等待一个固定量时间,或完全不等待) select从内核返回后内核会告诉我们: (1) 已准备好的描述符的数量。 (2) 哪一个描述符已准备好读、写或异常条件。 select 用于查询设备的状态,以便用户程序获知是否能对设备进行非阻塞的访问,需要设备驱动程序中的poll 函数支持。 驱动程序中 poll 函数中最主要用到的一个 API 是 poll_wait,其原型如下: void poll_wait(struct file *filp, wait_queue_heat_t *queue, poll_table * wait); poll_wait 函数所做的工作是把当前进程添加到 wait 参数指定的等待列表(poll_table)中。 需要说明的是,poll_wait 函数并不阻塞,程序中 poll_wait(filp, &outq, wait)这句话的意思并不是说一直等待 outq 信号量可获得,真正的阻塞动作是上层的 select/poll 函数中完成的。select/poll 会在一个循环中对每个需要监听的设备调用它们自己的 poll 支持函数以使得当前进程被加入各个设备的等待列表。若当前没有任何被监听的设备就绪,则内核进行调度(调用 schedule)让出 cpu 进入阻塞状态,schedule 返回时将再次循环检测是否有操作可以进行,如此反复;否则,若有任意一个设备就绪,select/poll 都立即返回。 应用程序调用select() 函数,系统调用陷入内核,进入到: SYSCALL_DEFINE5 (sys_select)----> core_sys_select -----> do_select() do_select大概的思想就是:当应用程序调用select() 函数, 内核就会相应调用 poll_wait(), 把当前进程添加到相应设备的等待队列上,然后将该应用程序进程设置为睡眠状态。直到该设备上的数据可以获取,然后调用wake up 唤醒该应用程序进程。

ActiveX控件实现IobjectSafety接口

如果没有实现IobjectSafety接口浏览器会提示交互不安全等信息 打开工程名Ctl.h 搜索 class C工程名Ctrl : public COleControl 在其上面添加 #include <objsafe.h> 搜索 DECLARE_DYNCREATE(C工程名Ctrl) 下面添加 DECLARE_INTERFACE_MAP() BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety) STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions ); STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions ); END_INTERFACE_PART(ObjSafe); 打开工程名Ctl.cpp 搜索 BOOL C工程名Ctrl::C工程名CtrlFactory::UpdateRegistry(BOOL bRegister) / // Interface map for IObjectSafety BEGIN_INTERFACE_MAP(CDxrOcxCtrl, COleControl) INTERFACE_PART(CDxrOcxCtrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP() / // IObjectSafety member functions // Delegate AddRef, Release, QueryInterface ULONG FAR EXPORT CDxrOcxCtrl::XObjSafe::AddRef() { METHOD_PROLOGUE(CDxrOcxCtrl, ObjSafe) return pThis->ExternalAddRef(); } ULONG FAR EXPORT CDxrOcxCtrl::XObjSafe::Release() { METHOD_PROLOGUE(CDxrOcxCtrl, ObjSafe) return pThis->ExternalRelease(); } HRESULT FAR EXPORT CDxrOcxCtrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(CDxrOcxCtrl, ObjSafe) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; const DWORD dwNotSupportedBits = ~dwSupportedBits; / // CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions // Allows container to query what interfaces are safe for what.

查找算法

一、顺序查找(Seauential Search)(静态查找) int SeqSearch(int s[],int n,int key) { int i; for(i=0;i<n && s[i]!=key;i++) ; if(i<n) return i; else return -1; } 二、折半查找 (Binary Search) (静态查找) 又称为二分查找,这种查找方法要求查找表的数据时线性结构保存,并且还要求查找表中的数据时按关键字由小到大有序排列。折半查找是一种递归过程。 最坏情况下,折半查找比较的次数O(nlog2n),其查找效率比顺序查找要快很多。 int BinarySearch(int s[],int n,int key) { int low,high,mid; low=0; high=n-1; while(low<=high) //查找范围含含至少一个元素 { mid=(low+high)/2; //计算中间位置序号 if(s[mid]==key) //中间元素与关键字相等 return mid; //返回序号 else if(s[mid]>key) //中间元素大于关键字 high=mid-1; //重定义查找范围 else //中间元素小于关键字 low=mid+1; //重定义查找范围 } return -1; //返回查找失败 } 优点:查找速度快,最多查找次数为O(nlog2n)。 缺点:对查找表中的数据有顺序要求,如果需要将查找不成功的关键字添加到查找表中,则需要对已有的查找表中的数据进行大量的移动。 三、二叉排序树 (Binary Sorting Tree) (动态查找) 1、插入节点

内存和CPU匹配方法详解

目录 1.内存和CPU的有关数据 2.内存跟CPU搭配的基本原则 3.在Intel平台实现频率同步的方法 4.在Intel平台实现带宽相等的计算方法 5.在Intel平台用主板调控内存运行参数的方法 6.在Intel 平台没有FSB了,怎么配内存 7.内存的双通道的设置问题 8.在AMD K8以前配置内存的方法 9.在AMD K8时代内存的选配方法 10.在AMD K10平台内存的选配方法 11.内存选配方法实例问答 12.内存和CPU配合实测结果的分析(见另文) 自从本人发表过《内存知识160问》后,受到网友们的热情关注。其中对内存如何跟CPU搭配始终是热门话题,仅一篇有关讨论内存跟CPU匹配的文章,在短短两三个月的时间,就有60余人次发表了评论。而且在评论中基本上都给予了积极地评价。这是很令人感动的。但是,在网上还有各式各样的说法,有许多说法,我不敢苟同。为此,我想把对这个问题的观点归纳一下,并把解决这个问题的方法表格化、数值化,以便使初步接触这个问题的网友能够自主进行计算,如果不会计算,你从我给出的表格中也会得到答案的。但是,可能有不妥之处。谨供网友们参考。 1.内存和CPU的有关数据 在正式讨论问题之前,我们首先要把内存的核心频率、时钟频率和数据频率之间的关系搞清楚,而且应该特别熟悉。这是讨论这个问题的基础。见下表: 表1 内存名称及各种频率列表 由表1可见,核心频率、时钟频率和数据频率之间有固定的关系。它们之间的比例关系见表2。 表2. 内存的核心频率、时钟频率和数据频率之间的比例关系 其中的核心频率又称颗粒频率或基本频率;时钟频率又称工作频率、内存频率、I/O频率、DRAM、DRAM Frequency、时脉或内存速度;数据频率又称等效频率或传输通道频率。本文只采用“核心频率”、“时钟频率”和“数据频率”三个名称。对这些名称一定要弄清楚。 另外,有关CPU的名称也是五花八门的。例如,主频又称Core Speed;外频的名称就更多了,如Bus Speed 、汇流排频率、FSB(和前端总线混用)等。 2.内存和CPU搭配的基本原则 我认为:无论你采用的CPU是Intel的,还是AMD的,当选配内存时都必须遵守三条基本原则。 第一条是频率要同步:即内存的核心频率要等于或稍大于CPU的外频。不要给内存加上它不能承受的高频率,否则是频率“过载”。频率“过载”后,内存将拒绝工作。这样,电脑是要蓝屏的。当然,你给它加上低于核心频率的频率时,它会是胜任愉快的。 第二条是带宽要匹配:应该设法使内存的数据带宽跟CPU前端总线的带宽相等,否则,数据的传输能力将受制于带宽较低的那端; 第三条是主板要调控:因为以上两个条件有时是不可能同时能满足的。这就要靠主板来调控,调控的主要方法是异步设置。因为第一条是有关生或死的问题,所以,这一条必须满足。第二条就可以灵活处理了。 另外,当讨论内存跟CPU如何搭配时,必须明确以下事项: ①内存的核心频率小于外频时,内存会拒绝工作。表现是蓝屏。但是,在任何情况下,内存的核心频率大于CPU的外频时,内存都能正常工作。但是,系统也不会承认它的高频率。只承认它的核心频率等于外频。例如,你将DDR2-1066插入外频是200MHz的板子上时,系统将认为这个内存是DDR2-800。 ②Intel处理器的前端总线频率(FSB)是外频频率的4倍。但是,在历史上前端总线的频率和外频是同一个,所以,人们还是经常用FSB来表示外频(例如软件CPU-Z就是这样,它表示的“FSB:DRAM”实际上是指“CPU的外频:内存的时钟频率”)。 AMD的内存,在K8以前,也有前端总线,不过,那时的前端总线频率是外频频率的两倍。K8以后AMD的CPU就没有前端总线了。 ③当讨论内存跟Intel平台的CPU的匹配时,必须知道CPU的外频或前端总线频率。知道一个就行,因为它们之间是四倍关系,此时,不必关心CPU的主频是多少。 不过,自从有了Intel的i3/i5/i7后,参照的CPU频率已经不是外频和前端总线FSB,而是基本频率BF了。但是,在检测软件CPU-Z中,还是把BF频率称为外频的。在这种情况下,怎样配内存,请参看本文之6。 ④当讨论内存跟AMD平台的CPU匹配时,首先必须明确这个CPU是K8的?K10的?还是K8以前的?因为这三种CPU陪内存的方法是截然不同的。 讨论K8以前的CPU时,只需知道外频或FSB;讨论给K8的CPU配内存时,只需知道CPU的主频,不要提HT总线,因为配内存跟HT总线无关;同样的原因,当为K10配内存时,如果你不超频,只需知道CPU或主板支持什么内存就可以了。因为K10架构的CPU配内存时是跟外频挂钩的,而AMD CPU的外频是固定在200 MHz的。 ⑤当讨论内存跟CPU的搭配关系时,是根据内存和CPU的参数计算的,不必考虑主板。但是,当你对搭配方案作出选择后,还必须考虑主板是否支持。在一般情况下,主板的频率是应该高于FSB的频率的。 ⑥内存的异步就是使加给内存的频率是它能正常工作的频率。一般是指降频。但是,频率降下来的后果就是速度变慢和带宽变窄。所有主板都支持内存异步运行的。但是,支持的程度不同。 ⑦从内存跟CPU是否搭配的角度看,配内存时,不必考虑内存的容量是多少。但是,容量超过一定大小时,有时是要考虑主板是否支持的。 ⑧内存跟CPU是否匹配,跟CPU是几个核没有什么关系。 以上就是我认为内存匹配的三大原则和八项注意。 3.在Intel平台实现频率同步的方法 在Intel平台,内存频率跟CPU同步的条件就是:内存的核心频率必须等于或稍大于CPU的外频。否则,就是“频率过载”,内存将停止工作,主要的表现形式是蓝屏。 虽然对我这个说法经常听到不同的声音。但是,我坚信我的这个归纳方法是完全能站得住脚的。因为内存能够耐受多大的频率,完全是由核心频率决定的。时钟频率和数据频率都是在核心频率的基础上,通过技术手段放大出来的。当核心频率相等时,不同类型的内存会有不同的时钟频率和数据频率。 例如,在Intel平台,当外频是200MHz时,为了实现频率同步,应该选DDR-400、DDR2-800或DDR3-1600。因为这几种内存的核心频率都是200MHz。 这是十分重要的一条规律。但是,过去,人们都是把内存的同步条件说成“内存的时钟频率(而不是说“内存的核心频率”)等于或稍大于外频频率就是同步”。更多的是模棱两可的说法,比如说“内存的频率等于或稍大于外频,就是同步”。至今在网上的许多文章还是这样说的。相当混乱。 我认为,在SD和DDR时代,说“时钟频率和核心频率相等就是同步”,是完全正确的。但是,在DDR2和DDR3出现以后,再这样说就是完全错误的,因为不同类型的内存。其核心频率跟时钟频率是不同的。因此,两种判别方法存在巨大差异。 不过,囿于习惯,人们还是愿意用时钟频率来跟CPU的外频对比。我认为,按时钟频率跟CPU频率对比的方法来判断内存是否同步也不是不可以的。但是,必须把这个比作适当改动。比如说:“对于SDRAM和DDR,当内存的时钟频率跟CPU的外频相等时,就是内存同步。例如,当外频是200MHz时,应该配DDR-400的内存”;对于DDR2,就应该说:“当内存的时钟频率是外频的两倍时,就是内存同步。例如,当外频是200MHz时,应该配DDR2-800内存”;对于DDR3,就应该说:“当内存的时钟频率是外频的4倍时,就是内存同步。例如当外频是200MHz时,就应该配DDR3-1600内存”。这样说不是太啰嗦了吗! 可是,在检测软件CPU-Z中,就是用CPU的外频(此处称其为FSB)跟时钟频率(此处称为DRAM)的比值关系表示内存是否同步的的。其关系见下表: 表3 内存同步时,CPU的外频跟内存的时钟频率的频率关系 内存的类型 DDR DDR2 DDR3 FSB:DRAM(即CPU的外频跟内存时钟频率之比) 1:1 1:2 1:4 注:在检测软件CPU-Z中,就是用“FSB”表示CPU的外频的,这是历史形成的误用。上表中的“DRAM”是指时钟频率。

b MAIN 和 ldr pc,=MAIN 的区别(谈到代码位置无关性)

看bootloader的时候经常看到这两种写法,不太明白区别,网上查了查。其实看了之后还是一头雾水? 其中,2和3 似乎是一个东西,但结果是相反的。晕。 //=============================================== 有几种说法: 第一种,说寻址范围不同。(http://bulo.mcuol.com/GaoKefang/view.htm?topicID=126) LDR指令可以全地址范围内跳转,而B指令只能在前后32MB范围内跳转; 第二种,(http://www.onlyblog.com/blog2/CANopen/4491.html ) 一般芯片具有Re-Map功能,当向量表被重新映射至内部RAM或外部存储器中时用B指令不能实现正确跳转。(原因呢?,by imjacob,难道讲的是下面 程序设计规范2的情况 ?? ) 第三种, B指令经汇编后会替换为当前PC值加上一个修正值(+/-),所以这条指令是代码位置无关的,也就是不管这 条指令是在0地址还是在0x100000执行,都能跳转到指定的位置,而LDR PC,=???将向PC直接装载一个标号的值,请注意,标号在编译过后将被替换为一个与RO相对应的值,也就是说,这样的指令无论在哪里执行,都只会跳转 到一个指定的位置. (http://blog.cec.pandabuying.com/zhiy66/212528.aspx) 下面是它的详细解释: 以下假设: 芯片 FLASH起始于0x100000,共64kB,片上RAM起始于0x200000,共16kB. 芯片 复位之后,程序会从0开始执行,此时FLASH被映射到0地址,因此,芯片可以取得指令并执行.显然,此时还是驻留在0x100000地址.如果使用remap命令,将会把RAM映射到0地址,同样的这时0地址的内容也只是RAM的镜像. 假定有如下程序: RESET B INIT 或者 LDR PC,=INIT … INIT … 其中RESET为起始时的代码,也就是这条代码的偏移为0,设INIT的偏移量为offset.如果将这段程序按照RO=0x100000编译, 那么B INIT可理解为ADD PC, PC, #offset,而LDR PC,=INIT可被理解为 MOV PC,#(RO+offset) .显然当系统复位时,程序从0开始运行,而0地址有FLASH的副本,执行B INIT将把PC指向位于0地址处的镜像代码位置,也即INIT(应该是offset,by imjacob);如果执行LDR PC,=INIT将会将PC直接指向位于FLASH中的原始代码.(应该是 0x100000 + offset,by imjacob)因此以上两者都能正确运行. 下面将RO设置为0x200000,编译后生成代码,还是得 烧写到FLASH中,也就是还是0x100000,系统复位后从0地址执行,还是FLASH的副本,此时执行B INIT,将跳到副本中的INIT位置执行( 此时是0x100000+offset 还是 offset?,by imjacob) ,此处有对应的代码;但是如果执行LDR PC,=INIT,将向PC加载0x200000+offset,这将使得PC跳到RAM中,而此时由于代码没有复制,RAM中的指定位置并没有代码,程 序无法运行 (应该是 0x200000 + offset,by imjacob) . (我的理解:这就是位置无关代码的基本原理)

移动设备管理

面对移动设备带来的各种挑战,MDM能够帮助企业解决的问题包括: 支持哪些类型的移动设备;是否允许员工选择并携带他们的移动设备参与办公;如何处理移动设备的安全问题,比如当移动设备丢失时,是否有能力进行远程数据擦除等。 Link: http://security.zdnet.com.cn/security_zone/2013/0125/2142629.shtml