DDR3详解(以Micron MT41J128M8 1Gb DDR3 SDRAM为例)

首先,我们先了解一下内存的大体结构工作流程,这样会比较容量理解这些参数在其中所起到的作用。这部分的讲述运用DDR3的简化时序图。 DDR3的内部是一个存储阵列,将数据“填”进去,你可以它想象成一张表格。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,那么这个表格(存储阵列)就是逻辑 Bank(Logical Bank,下面简称Bank)。 DDR3内部Bank示意图,这是一个NXN的阵列,B代表Bank地址编号,C代表列地址编号,R代表行地址编号。 如果寻址命令是B1、R2、C6,就能确定地址是图中红格的位置 目前DDR3内存芯片基本上都是8个Bank设计,也就是说一共有8个这样的“表格”。 寻址的流程也就是先指定Bank地址,再指定行地址,然后指列地址最终的确寻址单元。 目前DDR3系统而言,还存在物理Bank的概念,这是对内存子系统的一个相关术语,并不针对内存芯片。内存为了保证CPU正常工作,必须一次传输完CPU 在一个传输周期内所需要的数据。而CPU在一个传输周期能接受的数据容量就是CPU数据总线的位宽,单位是bit(位)。控制内存与CPU之间数据交换的北桥芯片也因此将内存总线的数据位宽等同于CPU数据总线的位宽,这个位宽就称为物理Bank(Physical Bank,有的资料称之为Rank)的位宽。目前这个位宽基本为64bit。 在实际工作中,Bank地址与相应的行地址是同时发出的,此时这个命令称之为“行激活”(Row Active)。在此之后,将发送列地址寻址命令与具体的操作命令(是读还是写),这两个命令也是同时发出的,所以一般都会以“读/写命令”来表示列寻址。根据相关的标准,从行有效到读/写命令发出之间的间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟,RAS就是行地址选通脉冲,CAS就是列地址选通脉冲),我们可以理解为行选通周期。tRCD是DDR的一个重要时序参数,广义的tRCD以时钟周期(tCK,Clock Time)数为单位,比如tRCD=3,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,DDR3-800,tRCD=3,代表30ns的延迟。 图中显示的是tRCD=3 接下来,相关的列地址被选中之后,将会触发数据传输,但从存储单元中输出到真正出现在内存芯片的 I/O 接口之间还需要一定的时间(数据触发本身就有延迟,而且还需要进行信号放大),这段时间就是非常著名的 CL(CAS Latency,列地址脉冲选通潜伏期)。CL 的数值与 tRCD 一样,以时钟周期数表示。如 DDR3-800,时钟频率为 100MHz,时钟周期为 10ns,如果 CL=2 就意味着 20ns 的潜伏期。不过CL只是针对读取操作。 由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责,一个存储体对应一个S- AMP通道。但它要有一个准备时间才能保证信号的发送强度(事前还要进行电压比较以进行逻辑电平的判断),因此从数据I/O总线上有数据输出之前的一个时钟上升沿开始,数据即已传向S-AMP,也就是说此时数据已经被触发,经过一定的驱动时间最终传向数据I/O总线进行输出,这段时间我们称之为 tAC(Access Time from CLK,时钟触发后的访问时间)。 图中标准CL=2,tAC=1 目前内存的读写基本都是连续的,因为与CPU交换的数据量以一个Cache Line(即CPU内Cache的存储单位)的容量为准,一般为64字节。而现有的Rank位宽为8字节(64bit),那么就要一次连续传输8次,这就涉及到我们也经常能遇到的突发传输的概念。突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输的周期数就是突发长度(Burst Lengths,简称BL)。 在进行突发传输时,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期(主要是之前的延迟,一般的是tRCD+CL)外,其后每个数据只需一个周期的即可获得。 突发连续读取模式:只要指定起始列地址与突发长度,后续的寻址与数据的读取自动进行,而只要控制好两段突发读取命令的间隔周期(与BL相同)即可做到连续的突发传输。 谈到了突发长度时。如果BL=4,那么也就是说一次就传送4×64bit的数据。但是,如果其中的第二笔数据是不需要的,怎么办?还都传输吗?为了屏蔽不需要的数据,人们采用了数据掩码(Data I/O Mask,简称DQM)技术。通过DQM,内存可以控制I/O端口取消哪些输出或输入的数据。这里需要强调的是,在读取时,被屏蔽的数据仍然会从存储体传出,只是在“掩码逻辑单元”处被屏蔽。DQM由北桥控制,为了精确屏蔽一个P-Bank位宽中的每个字节,每个DIMM有8个DQM 信号线,每个信号针对一个字节。这样,对于4bit位宽芯片,两个芯片共用一个DQM信号线,对于8bit位宽芯片,一个芯片占用一个DQM信号,而对于 16bit位宽芯片,则需要两个DQM引脚。 在数据读取完之后,为了腾出读出放大器以供同一Bank内其他行的寻址并传输数据,内存芯片将进行预充电的操作来关闭当前工作行。还是以上面那个Bank示意图为例。当前寻址的存储单元是B1、R2、C6。如果接下来的寻址命令是B1、R2、C4,则不用预充电,因为读出放大器正在为这一行服务。但如果地址命令是B1、R4、C4,由于是同一Bank的不同行,那么就必须要先把R2关闭,才能对R4寻址。从开始关闭现有的工作行,到可以打开新的工作行之间的间隔就是tRP(Row Precharge command Period,行预充电有效周期),单位也是时钟周期数。 在不同Bank间读写也是这样,先把原来数据写回,再激活新的Bank/Row。 数据选取脉冲(DQS) DQS 是DDR中的重要功能,它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。每一颗芯片都有一个DQS信号线,它是双向的,在写入时它用来传送由北桥发来的DQS信号,读取时,则由芯片生成DQS向北桥发送。完全可以说,它就是数据的同步信号。 在读取时,DQS与数据信号同时生成(也是在CK与CK#的交叉点)。而DDR内存中的CL也就是从CAS发出到DQS生成的间隔,DQS生成时,芯片内部的预取已经完毕了,由于预取的原因,实际的数据传出可能会提前于DQS发生(数据提前于DQS传出)。由于是并行传输,DDR内存对tAC也有一定的要求,对于DDR266,tAC的允许范围是±0.75ns,对于DDR333,则是±0.7ns,有关它们的时序图示见前文,其中CL里包含了一段DQS 的导入期。 DQS 在读取时与数据同步传输,那么接收时也是以DQS的上下沿为准吗?不,如果以DQS的上下沿区分数据周期的危险很大。由于芯片有预取的操作,所以输出时的同步很难控制,只能限制在一定的时间范围内,数据在各I/O端口的出现时间可能有快有慢,会与DQS有一定的间隔,这也就是为什么要有一个tAC规定的原因。而在接收方,一切必须保证同步接收,不能有tAC之类的偏差。这样在写入时,芯片不再自己生成DQS,而以发送方传来的DQS为基准,并相应延后一定的时间,在DQS的中部为数据周期的选取分割点(在读取时分割点就是上下沿),从这里分隔开两个传输周期。这样做的好处是,由于各数据信号都会有一个逻辑电平保持周期,即使发送时不同步,在DQS上下沿时都处于保持周期中,此时数据接收触发的准确性无疑是最高的。 在写入时,以DQS的高/低电平期中部为数据周期分割点,而不是上/下沿,但数据的接收触发仍为DQS的上/下沿 3.容量的计算 上图为X8data的单颗DDR3架构图,行(Row)地址线复用14根,列(Column)地址线复用10根,Bank数量为8个,IO Buffer 通过8组数位线(DQ0-DQ7)来完成对外的通信,故此单颗DDR3芯片的容量为2的14次方乘2的10次方乘8乘8,结果为1Gbit,因为1B包含8bit,1GB/8=128MB。 如果我们要做成容量为1GB的内存条则需要8颗这样的DDR3内存芯片,每颗芯片含8根数位线(DQ0-DQ7)则总数宽为64bit,这样正好用了一个Rank。 假果还用128MB的DDR3芯片去做2GB内存条,结果就会有所不同。我们最好选用4根数位线(DQ0-DQ3),数量是16颗,这样也是用了一个Rank。

带戒指的讲究

右手小指:不谈恋爱。 右手无名指:热恋中。 右手中指:名花有主。 右手食指:单身贵族 左手小指:不婚族。 左手无名指: 结婚。 左手中指: 订婚。 左手食指: 未婚 按照我国的习惯, 订婚戒一般戴在左手的中指, 结婚戒指戴在左手的无名指; 未婚姑娘应戴在右手的中指或无名指。 国际上比较流行的戴法是: 戴在拇指——自我、率性;正在寻觅对象 戴在食指——已有情人;想结婚而尚未结婚。 戴在中指——处于热恋之中,订婚 戴在小指——表示单身或离婚或决心独身 无名指上——已订婚或结婚 右手无名指——表示具有修女的心性。 戴设计性比较强的戒指时,可以和表搭配 

Linux 下利用netem模拟广域网特性

一、netem 与 tc: netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块。该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带宽、传输延迟、丢包等等情况。使用 Linux 2.6 (或以上) 版本内核的很多发行版 Linux 都开启了该内核功能,比如Fedora、Ubuntu、Redhat、OpenSuse、CentOS、Debian等等。 tc 是 Linux 系统中的一个工具,全名为traffic control(流量控制)。tc 可以用来控制 netem 的工作模式,也就是说,如果想使用 netem ,需要至少两个条件,一个是内核中的 netem 功能被包含,另一个是要有 tc 。 需要注意的是:本文介绍的流控只能控制发包动作,不能控制收包动作,同时,它直接对物理接口生效,如果控制了物理的eth0,那么逻辑网卡(比如eth0:1)也会受到影响,反之,如果您在逻辑网卡上做控制,该控制可能是无效的。(注:虚拟机中的多个网卡可以在虚拟机中视为多个物理网卡)。 二、模拟延迟传输 # tc qdisc add dev eth0 root netem delay 100ms 该命令将 eth0 网卡的传输设置为延迟100毫秒发送。 更真实的情况下,延迟值不会这么精确,会有一定的波动,我们可以用下面的情况来模拟出带有波动性的延迟值: # tc qdisc add dev eth0 root netem delay 100ms 10ms 该命令将 eth0 网卡的传输设置为延迟 100ms ± 10ms (90 ~ 110 ms 之间的任意值)发送。 还可以更进一步加强这种波动的随机性: # tc qdisc add dev eth0 root netem delay 100ms 10ms 30% 该命令将 eth0 网卡的传输设置为 100ms ,同时,大约有30%的包会延迟 ± 10ms 发送。

struts2 提交表单

提交表单 struts2 不再像struts1 那样需要一个form bean ,当然也不需要在struts.xml中绑定form bean。直接在action中就可以获得各个表单域的值。 以登录表单和登录action举例说明: 一、页面中表单loginForm 包含两个域 姓名域:userName 和密码域:password 。 <form name="loginForm" action="login.do" method="POST"> name:<input type="text" name="userName" id="userName" value="" /> password:<input type="password" name="password" id="password" /> <input type="submit" name="loginBt" id="loginBt" value="login"/> </form> 二、登录的action : import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport{ Logger logger = Logger.getLogger(ActionSupport.class); private String userName =""; //定义userName 属性 private String password =""; //定义password属性 public String getUserName() {

006:__Main介绍(ADS下)(转)

__Main 在软件仿真的情况下,执行“B __main”指令,能使程序跳到C文件的main函数,但用硬件仿真时,还没执行到main函数时就进入了异常中断。 原因是执行“B __main”指令后,程序先跳到__main库函数的入口,再进行一些初始化操作,最后再跳入用户的main函数。但在初始化过程中,由于堆栈或其它原因造成程序出错。有两种方法可以解决这个问题。第一:将“B __main”指令直接改成“B main”,使程序不进行初始化而直接跳入用户的main()函数。第二:合理初始化堆栈。由于考虑到刚接触ARM和将问题简单化,我选择了第一种方法。 第二种答案如下: IMPORT __main .... .... BL TargetResetInit B __main 1、此后流程将跳转到ADS提供的启动代码__main函数处,负责完成库函数的初始化及相关功能,并最终引导处理器入口用户代码main()函数,其代码流程为: 嵌入式系统在进入应用主程序之前必须有一个初始化的过程,该过程完成系统的启动和初始化功能,初始化过程可以分成两部分来看: √ _main负责设置运行映像存储器映射; √ _rt_entry负责库函数的初始化。 _main完成代码和数据的复制,并把ZI数据区清零,这一步当代码和数据区在存储和运行时处于不同的存储器位置时有意义。接着_main跳进_rt_entry,进行STACK和HEAP等的初始化。最后_rt_entry跳进应用程序的入口main()。当应用程序执行完时,_rt_entry又将控制权交还给C库函数,函数main()在ADS中有特殊的意义。当一个程序工程项目中存在main()时,连接器会把_main和_rt_entry中的初始化代码连接进来;如果没有main()函数,初始化过程就不会被连接,初始化过程中一些标准的C库函数失效。而用户应用程序初始化过程并未显式的完成这些堆栈初始化及数据拷贝操作,应用程序将启动不成功。 2、__main()为编译系统提供的一个库函数,使用__main标号引导系统时必须将应用程序的入口数定义为main(); 3、若希望系统进入应用程序前自动完成系统调用(如库函数的初始化、RW、ZI数据从Flash到RAM的拷贝(加载映像--->执行映像)等)的初始化过程,必须使用__main标号以跳至ADS提供的初始化函数库,这种情况一般需做一些库函数移植及重定向问题解决;这一点上,应用程序入口必须以main函数标识; 4、若所有的初始化步骤都已显式的完成(如堆栈初始化、加载映像到执行映像RW、ZI数据的拷贝等),应用程序入口函数XXXX()可以任意定义(非main,这样可以避免自动链接上__main,从而跳过__main),初始化完成后直接B XXXX即可,这一点上,main()函数并不具有特殊性; 5、若必须的初始化步骤都未显示的完成,一意孤行的B XXXX,程序运行的结果将不可预料。一个典型的例子是:若用户并未显示完成加载映像--->执行映像的数据初始化而直接B XXXX,则应用程序中所有的全局变量并不会被预期的初始化,而所有的ZI变量也不会被预期的清零; 6、本人在调试LPC2294 LCD模块时才认识到上述第五点(5、)的重要性:程序指令流并没有错,但LCD上显示的全部是乱码。我用两种方法解决了这一bug: (1)将所有的字库数据定义为const常量,程序运行正确; (2)将B Main 修改成B __main接着将应用入口改为int main(void) 而非int Main(void),程序也得到正确的执行; Initializing memory required by C code The initial values for any initialized variables (RW) must be copied from ROM to RAM. All other ZI variables must be initialized to zero.

深入探索3D拾取技术

-潘宏 -2013年1月 -本人水平有限,疏忽错误在所难免,还请各位高手不吝赐教 -email: popyy@netease.com -weibo.com/panhong101 3D拾取 在游戏中,玩家需要通过点击2D屏幕来选择3D物体,这个过程就是拾取(picking)。拾取是3D游戏必不可少的基本操作,它实现了玩家和游戏世界内对象的交互。 虽然拾取技术很基本,但它却迷惑了很多3D初学者。很多朋友都问过我关于拾取的细节问题,这让我觉得很有必要具体探讨一下该技术。 其实,拾取之所以让很多开发者感到复杂,主要原因在于它跨域了流水线的多个阶段,并且是逆流水线上行。另外,它是一个2D信息扩展到3D的过程,必须对信息做相应的扩展和额外的计算才能够得到正确的结果。下面我门具体分析一下这个技术。 水流线主要阶段分析 我们来直观地看一下从相机空间到viewport的变换图: 相机空间中的一个顶点v,经过透视变换后进入了CVV中。这个变换矩阵实际上完成了两个工作: 1)将顶点从3D空间投影到2D的投影平面(Projection Plane)上。 2)将投影平面上的2D投影点通过线性插值变换到齐次裁剪空间CVV中。 这些变换都通过透视矩阵一次完成(如果对此不是很了解,请参考《深入探索透视投影变换》一文)。 我之所以把这一步分解为两步,因为这对于分析拾取很重要。 顶点进入齐次裁剪空间并经过CVV裁剪,最终进行透视除法从4D齐次形式变回成3D形式。然后经过一个线性插值(被封装在视口(viewport)变换中),变换到viewport中,多个点以三角形的形式经过光栅化后被玩家看到。最后一步的点变换可以描述为: 3)将CVV中的点通过线性插值变换到viewport中。 分析了这个变换过程之后,我们知道了从相机空间开始实际处理点位置信息的操作,就是上面的三个步骤。这样,我们可以先把顶点从viewport中先变换回投影平面上,也就是我们可以先完成(2)和(3)的逆处理。这里我们不用考虑裁剪和透视除法这些操作,因为反推的时候,处于视口中的点,已经是经过裁剪后留下的有效点了,必定处于CVV内,也必定处于projection plane内!而且从viewport逆变换到projection plane,点一直保持2D形式。 picking的开始是玩家在屏幕上点击一个位置——这实际上是在viewport中进行了点击。我们通过响应玩家的点击事件,得到在viewport中的点击位置,记为P0(Xp0,Yp0)。然后我们把p0从viewport中线性插值到CVV中,得到P1(Xp1,Yp1): 上面的线性插值(如果对线性插值公式不熟悉,请参考《深入探索透视投影变换》一文中的线性插值部分)公式在x方向上计算出了CVV中的P1,y方向的公式同理。接下来我们再把P1从CVV中变换到projection plane中,得到P2(Xp2,Yp2): y方向的计算同理。P2就是viewport中玩家点击的点在projection plane上所对应的位置。 目前来看很好。我们已经获得了相机空间中的投影平面上,玩家点击的位置。但目前的点是一个2D点——它处于投影平面上。玩家需要拾取的是一个3D对象,因此我们需要将2D信息拓展到3D中。 向3D世界拓展 将2D的点信息拓展到3D空间进行picking,会使用射线(ray)进行。ray就是一端固定,另一端无限延伸的线性模型。如下图所示: 在相机空间中,红线标明的就是用于picking的ray。它的固定端就是eye的位置(也就是相机空间的原点),并且穿过我们刚刚求出来的projection plane上面的点P2。射线向空间无限延伸,第一个穿过的polygon应该就是picking到的结果。在图中,有两个polygon被picking到:绿色和黄色的。其中黄色的polygon是第一个被穿过的,因此picking操作返回的结果就是这个polygon。在实现中,我们一般有两种方式来表示一个ray: struct Ray3D { Point3D m_startingPos; Point3D m_penetratedPos; }; struct Ray3D { Point3D m_startingPos; Point3D m_direction; }; 第一种方式标明了ray的起始点m_startingPos和任意一个穿过点m_penetrated。第二种方式标明了ray的起始点m_startingPos和方向m_direction。这两种方式可以很方便的相互转换。 在有了ray的表示法之后,我们要做的就是判断ray是否和各个polygon产生了相交——这实际上是一个射线和三角形的相交判断算法。这种算法很普遍,很容易找到,这里我们不进行讨论。最基本的拾取算法(相机空间中)如下所示; extern float ray_triangle_intersection( const Ray3D& ray, const Polygon& polygon ); GameObject* picking( const Point3D& P2, const std::vector< GameObject* >& objects ) { Ray3D ray; ray.

PDB文件详解

PDB格式文件对大部分做模拟和计算的人来说都很熟悉,但其中各个参数的意义很多人并不是很了解。从网上搜集了一些文章,结合自己的知识来对PDB文件中各个参数的意义做个解释: REMARK 该记录用来记述结构优化的方法和相关统计数据。如用Refmac进行结构优化,该记录将自动插入输出的PDB。 CRYST1 (NMR除外) 该记录用来记述晶胞结构参数 (a, b, c, α, β, γ, 空间群) 以及 Z值 (单位结构中的聚和链数)。 SCALEn(n = 1, 2, 3) (NMR除外) 该记录介绍数据中直角坐标向部分晶体学坐标的转换。 ATOM 该记录记述了标准氨基酸以及核酸的原子名,残基名,直角坐标,占有率,温度因子等信息。 HETATM 该记录记述了标准氨基酸以及核酸以外的化合物的原子名,残基名,直角坐标,占有率,温度因子等信息。 TER 该记录表示链的末端。在每个聚合链的末端都必须有TER记录,但是由于无序序列而造成的链的中断处不需要该记录。 MODEL 当一个PDB文件中包含多个结构时(例:NMR结构解析),该记录出现在各个模型的第一行。 MODEL记录行的第11-14列上记入模型序号。序号从1开始顺序记入,在11-14列中从右起写。比如说有30个模型,则第1至9号模型,该行的7-13列空白,在14列上记入1-9的数字;第10-30号模型,该行的7-12列空白,13-14列上记入 10-30的数字。 ENDMDL 与MODEL记录成对出现,记述在各模型的链末端的TER记录之后。 END 该记录标志PDB文件的结束,是必需的记录。 B-factoer The B-factor (or temperature factor) is an indicator of thermal motion about an atom. However, it should be pointed out that the B-factor is a mix of real thermal displacement, static disorder (multiple but defined conformations) and dynamic disorder (no defined conformation), and all the overlap between these definitions.

windows 无效驱动器 问题

安装时遇到“无效驱动器 W:” (盘符可能有很多种情况)。这是我ghost装Win7后, 在安装 jdk 时候遇见的, 这个问题也导致了 word 不能正常打开文件, 很多软件无法 安装。 解决方法是,首先, win7: 开始》右键打开 计算机 属性 》 左边的 高级系统设置 xp: 右键打开桌面上 我的电脑 的属性 》 高级 选项卡 然后,打开“环境变量”,应该会发现当前用户的环境变量里个 TEMP 和 TMP 两个 环境变量,值是报错的那个W:\userTemp (视个人情况而定),系统变量里面也有 TEMP 和 TMP ,值是 W:\sysTemp。 由于W:不存在导致的,把它改成你现有的某个盘就可以了,比如改成 C:\userTemp 和 C:\sysTemp 。 记得两个都要改!

Tracert和Ping的命令区别

Ping:主要就是检测目标主机是不是可连通。 实质:发送一个ICMP回显请求报文给目的主机,并等待回显的ICMP应答。然后打印出回显的报文。 注意:Ping不通一个地址,并不一定表示这个IP不存在或者没有连接在网络上,因为对方主机可能做了限制,比如安装了防火墙,因此Ping不通并不表示不能使用FTP或者TELNET连接。 结果:包括字节数、反应时间、以及生存时间。 Ping程序通过在ICMP报文数据中存放发送请求的时间来计算返回时间。当应答返回时,根据现在时间减去报文中存放的发送时间就得到反应时间了。生存时间(TTL),本来就存放在IP数据报的头部,直接就能够获取。 Tracert:一个探测路由的程序,可以让我们看见IP数据报到达目的地经过的路由。 实质:利用ICMP数据报和IP数据报头部中的TTL值。TTL(Time To Live)是一个IP数据报的生存时间,当每个IP数据报经过路由器的时候都回把TTL值减去1或者减去在路由器中停留的时间,但是大多数数据报在路由器中停留的时间都小于1秒种,因此实际上就是在TTL值减去了1。这样,TTL值就相当于一个路由器的计数器。 当路由器接收到一个TTL为0或者1的IP数据报的时候,路由器就不再转发这个数据了,而直接丢弃,并且发送一个ICMP“超时”信息给源主机。Tracert程序的关键就是这个回显的ICMP报文的IP报头的信源地址就是这个路由器的IP地址。同时,如果到达了目的主机,我们并不能知道,于是,Tracert还同时发送一个UDP信息给目的主机,并且选择一个很大的值作为UDP的端口,使主机的任何一个应用程序都不使用这个端口。所以,当达到目的主机的时候,UDP模块就产生一个“端口不可到达”的错误,这样就能判断是否是到达目的地了。 有说法是利用ping得到的TTL值来判断主机类型,这种办法可以大概地用来判断,有人问为什么一般得到的都不是标准的TTL值。这个就是因为ICMP数据包走的路由器线路的原因,所以,用ping 和 tracert 一起来用更容易判断主机类型(不过并不一定两次走的路线都一样,所以,还是个大概值,不过更接近点,而且主机的默认TTL值是可以改变的)。 C:\〉ping 211.99.199.204 Pinging 211.99.199.204 with 32 bytes of data: Reply from 211.99.199.204: bytes=32 time=20ms TTL=248 Reply from 211.99.199.204: bytes=32 time〈10ms TTL=248 Reply from 211.99.199.204: bytes=32 time=10ms TTL=248 Reply from 211.99.199.204: bytes=32 time=10ms TTL=248 Ping statistics for 211.99.199.204: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 20ms, Average = 10ms C:\〉tracert 211.

C++开源库

C++在“商业应用”方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年。因为当今商业应用程序类型,已经从桌面应用迅速转移成 Web应 用。当Java横行天下之后,MS又突然发力,搞出C#语言,有大片的曾经的C++程序员,以为C++要就此沉沦,未料,这三年来,C++的生命力突然被 严重地增强了。主力原因就是开源的软件、基础软件(比如并发原生支持,比如Android必定要推出原生的SDK)、各种跨平台应用的出现。 开源C++库必须具有以下特点:必须是成熟的产品、跨平台的产品、相对通用的库。 一、通用标准类 STL:C++标准模板库,呵呵,它也是开源的嘛。 boost:C++准标准库,它是强大地,江湖称之“千锤百炼”。 -------若掌握,必横行世界。 deelx (轻量级的正则表达式解析类库,国产),boost里有强大的正则表达式解析库,但如果你只想要一个表达式解析,不想要拖上庞大的boost库时……支持一下国货。 iconv /iconvpp : (C形式的编码转换函数库, 二、XML解析库 C++的XML相关库不少,但是大部分其实都是C库,使用起来自然不那么轻便。其中基于DOM的有TinyXml,基于SAX的当然是Xerces。前者小巧快捷,便于使用,适合做数据交换。后者则是全功能的XML解析器。 哥更倾向于TingyXml.小巧啊! xerces-c :最强大的XML解析库了,不是仅仅在开源库里,你尽管把商业的算在内。当然,它的变体,被IBM拿去卖钱的那个版本,多了数百兆的东东来支持各国编码转换,是更强大,但我觉得有小小的,开源的iconv在前不就够了? 根据博友的一篇博文http://www.cnblogs.com/wuqi924/archive/2010/11/18/1880950.html 对三个轻型xml解析开源库:SlimXml、TinyXml、RapidXml,对比如下: 解析这个3.3万行,1.5M大小的xml,三个库分别花了 SlimXml: 22msTinyXml: 54msRapidXml: 4ms! 结论是,RapidXml果然很强悍,居然比SlimXml快5倍多。 比较欣慰的是,在没有很关注效率的情况下,SlimXml仍然比TinyXml快 2.5倍。SlimXml走的是简单小巧路线,源代码只有 32k,而TinyXml和RapidXml的源码分别是147k和141k,有这样的效率可以满意了。因为这个库主要还是针对几十上百行的小文件,解析 特别大的xml不在我考虑的范围之内。 还有irrlicht(鬼火引擎)的irrXMl解析器。 xsd (XML 与 C++数据结构的绑定工具)。(商业使用要钱) 三、数据库 我比较喜欢OTL(用于连接数据库)。其他的没用过 四、多媒体类 ---摘录别处,自己,没用过 SDL (Simple DirectMedia Layer/多媒体直接访问层,用于游戏编程)。 相应的c开源库有ffmpeg、mpeg4、aac、avc、libmad、mpeg1、flac、ac3、ac3、matroska著名的多媒体播放器 TCPMP 天下闻名的跨平台、嵌入式手持设备视频播放器, 五、网络开发类 1、gSOAP SOAP协议的C++支持库及代码生成工具。 2、ACE 网络编程研究首选。 ACE适合于研究,大型网络编程上效率不足,大型网游里面几乎没有用到ACE的,很多用了ACE的项目也被证明了效率不高。 除了ACE之外,还有很多系统和网络编程方面的程序库。比如在线程库方面,还有ZThread、boost::thread,如果放大到C/C++ 领域, 还有APR,还有CII。在文件和目录操作方面,boost也有相应的组件,而在网络编程方面有socket++,还有boost::asio,未来的 C++0X中几乎肯定有一个网络编程和一个线程库。然而目前看来,ACE仍然是进行系统和高性能网络编程的首选,其地位在一段时间内不会被撼动。它不但是 一个实用的程序库、框架集,还是一个典范的设计模式应用范例,非常值得学习。 3、有博友回复到POCO。我整理如下: 开源C++库,称为POCO(POrtable COmponents – 可移植元件),非常方便好用。 特性: * 线程,程序同步及多线程编程高级抽象 * 流及文件系统访问

原型模式和单例模式的区别

原型模式和单例模式的区别 1. 定义上的区别 1.1. 原型模式 用原型模式是在已指定对象的基础上,然后通过拷贝这些原型对象创建新的对象。 当要实例化的类是在运行时刻指定或者为了避免创建一个与产品类层次平行的工厂类层次时或者当一个类的实例只能有几个不同状态组合中的一种时 —— 建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。 1.2. 单例模式 单态设计模式的核心就是:将类的构造方法私有化,之后在类的内部产生实例化对象,并通过静态方法返回实例化对象的应用。 如果不希望一个类产生更多对象的情况下,必须使用单态模式,所谓单态就是在对象的入口处(构造方法)限制了对象的实例化操作。 2. JAVA实现上的区别 2.1. 原型模式 import java.util.ArrayList; class ConcretePrototype implements Cloneable { private String name; private ArrayList<String> nameList = new ArrayList<String>(); public ConcretePrototype(String name) { this.name = name; this.nameList.add(this.name); } // 添加nameList中的对象 public void setName(String name) { this.nameList.add(name); } public ArrayList<String> getNameList() { return this.nameList; } // 覆盖Object基类中的clone()方法,并扩大该方法的访问权限,具体化返回本类型 public ConcretePrototype clone() { try { return (ConcretePrototype) super.clone(); } catch (CloneNotSupportedException e) { e.

在虚拟机上运行vxWorks

Vxworks是一个嵌入式系统,主要运行在arm、ppc、mips等嵌入式处理器上,它同样可以运行在X86处理器上。风河公司开发的tornado开发环境就 包括了pentium版本,并且发布了相应的bsp。因此我们可在vmware虚拟机上运行vxworks,利用虚拟机的功能,我们不需要额外的计算机硬件就可 以开始我们的实验。 系统引导 计算机系统上电后,首先需要执行引导程序,然后加载操作系统。嵌入式系统中一般是将引导程序(称之为bootrom)固化在ROM芯片(也称为 bootrom,指的是物理硬件)中。系统上电后执行ROM中的引导程序,将操作系统由flash(或硬盘)加载到内存。对于PC而言,系统上电后运行BIOS 程序,之后将软盘或则硬盘上的引导扇区载入内存执行引导过程,引导程序再将操作系统加载到内存中启动。vmware的虚拟硬盘开始时没有安装 引导程序,因此无法从硬盘引导。因此我们需要制作一个引导软盘来引导系统加载vxworks。我们的第一个实验就是编译引导程序镜像,制作引导 盘。 制作引导盘 首先要在你的PC上Tornado 2.2 for pcPentium开发环境。另外需要安装pcPentium的BSP包,这个软件包可以到风河公司的网站免费下载。 制作引导盘当然还需要一张软盘,但是目前的PC基本都不使用软盘软驱了(如果你的古董机还有软驱的话,那么恭喜你,你只需要一张软盘就搞定了)。 好在vmware可以直接使用软盘镜像并且可以直接创建软盘镜像,因此我们在vmware中安装一个虚拟的windowsxp系统,以便在虚拟的windowsXP系统中 将软盘镜像格式化,并制作启动软盘。当然也可以使用虚拟软驱RamDiskNT在主机上使用软盘镜像。 Ok,准备工作做好了,我们开始编译bootrom。你可以通过tornado集成开发环境的菜单命令build boot rom。 弹出build boot rom对话框,我们选择pcpentium BSP、编译bootrom、工具使用gnu 编译完成后可以在$WIND_BASE/target/config/pcPentium目录下找到编译出来的bootrom文件。 我们也可以使用命令行方式编译bootrom,进入cmd命令行界面,进入 $WIND_BASE/target/config/pcPentium目录,目录中有一个Makefile文件,我们就是使用这个makefile文件来编译bootrom。实际集成开发环境也是使用它 来编译的。编译之前我们需要设置一下所需的环境变量: set WIND_BASE=D:/Tornado2.2 set WIND_HOST_TYPE=x86-win32 实际上tornado已经提供了一个批处理文件用于设置相关的环境变量,这个文件就是 $WIND_BASE/host/x86-win32/bin/torVars.bat,我们也可以直接运行这个批处理 ../../../host/x86-win32/bin/torVars.bat 然后执行命令 make bootrom 就可以在$WIND_BASE/target/config/pcPentium目录下生成bootrom文件 把上面的命令写成一个批处理makeBootRom.bat,方便使用,内容如下: D:/tornado2.2/host/x86-win32/bin/torVars.bat cd %WIND_BASE%/target/ config/pcPentium make bootrom 好了,编译成功。下一步使用如下命令创建引导盘: mkboot a: bootrom mkboot.exe是tornado提供的制作启动盘的工具,a盘是软盘的盘符,bootrom就是我们的引导镜像文件。 将制作好的引导盘载入虚拟机中: 虚拟机上电后自动从软盘启动,出现如下界面。 是的,你没看错,系统确实已经成功启动,只不过vxworks系统默认是不接受任何输入输出的。因此我们看不到它运行的任何东西,也无法操作它。 这样一个界面让人很无语,这跟一个人变成了瞎子瘸子没什么分别。下一步,我们将console组件加入到bootrom中。 打开$WIND_BASE/target/config/pcPentium/config.h文件,找到 #undef INCLUDE_PC_CONSOLE /* PC keyboard and VGA console */ 将它改为: #define INCLUDE_PC_CONSOLE /* PC keyboard and VGA console */

MDE工程入门

目录结构如图: public 源目录:放置服务接口和依赖类(VO); private源目录:存放实现类 client源目录 :存放ui代码 gen :存放通过部署成成的文件 MDE工程必须把自动构建选项选上<Project->Build Automatically>,否则不能够进行自动的开发环境内容与基础技术平台调试运行内容保持同步。 Ø nc.itf.<模块>: 表示该模块定义的接口 Ø nc.impl.<模块>:表示该模块定义的接口实现 Ø nc.vo<模块>: 表示VO的实现 Ø nc.bs.<模块>: 普通的后台应用 Ø nc.ui.<模块>.*: 客户端代码 Ø 表示包模块的部分在包的第三个部分,如nc.bs.schedule,中的schedule,在

alsa config

#title:box:HDMI Audio #author:wangsijie #:0,1 ------------------------------------------------------------------------------ 硬件环境 Nvidia(290) ------------------------------------------------------------------------------ 软件环境 alsa-1.0.24.1-3.1 ------------------------------------------------------------------------------ 配置文件 /etc/asound.conf(简易配置) : {{{ pcm.!default{ type hw card 1 devive 7 } ctl.!default{ type hw card 1 device 7 } }}} 其中card代表声卡号, device代表设备号, asound.conf的配置极其强大和复杂,详情可查阅http://www.alsa-project.org/main/index.php/Main_Page --------------------------------------------------------------------------- card, device的确定方法 card, device必须对应hdmi的声卡号和设备号,可以使用aplay -l查看对应的hdmi设备,可能会有出现多个hdmi设备,确定当前可以使用的hdmi设备的方法如下: #. cat /proc/asound/cards 查看nvidia设备对应的ID号(假设=1) #. alsamixer -c 1 打开声音设置,其中<S/PDIF>即为HDMI输出,“MM”代表静音,alsa在每次重启声音设备时都会默认为静音,所以必须首先打开音量再进行后续的操作。 #. alsactl store 保存上述配置 #. aplay -D hw:1,7 /usr/share/sounds/alsa/test.wav "hw后的1代表声卡号,7代表设备号,需要根据aplay -l的输出来确定这两个数字"找到对应的hdmi输出口。 -------------------------------------------------------------------------------------------------------------------------------------------------------------- 参考网站: ALSA的配置文件对于ALSA非常重要。常见的有三个:alsa.conf, asoundrc, asound.conf。 1. 核心配置文件 ALSA核心配置文件位于/usr/share/alsa/目录下, 主要配置文件为/usr/share/alsa/alsa.

设计模式之工厂模式、抽象工厂模式、单例模式(C++代码)

设计模式的重要性就不用多说了。各种设计模式在实际项目中用的是比比皆是。 一:简单工厂模式和工厂模式 懂得一点UML,一看这幅类图,就知道工厂模式是用来干嘛的,说白了,就是提供一个抽象的基类接口,使得用户不用记住具体的要成成的新的类的名字。 下面 看一段代码: [cpp] view plain copy #include<iostream> #include<string> #include<vector> using namespace std; class Product { public: Product(){} ~Product(){}; }; class ProductA:public Product { public: ProductA(){cout<<"ProductA"<<endl;} ~ProductA(){} }; class Factory { public: Factory(){} ~Factory(){} ProductA* createProductA() { return new ProductA(); } }; int main() { Factory f;//简单工厂模式 ProductA* pa=f.createProductA(); system("pause"); return 0; } 这里只列举了一个产品,可以自行扩展多个产品,比如产品都有:香蕉、苹果、橘子等等。指需要通知一声工厂,工厂就会调用相应的 生产香蕉、生产苹果、生产橘子等函数、而客户不需要知道生产这些水果的具体过程。坐着等吃就行。 工厂模式的类图如下,具体代码省。。 二 :抽象工厂模式 上面 所讲的工厂模式还不够抽象,因为只有产品抽象了,工厂并未抽象,上面所讲的是一个工厂生产了所有需要的产品,但是,你想想,假设HTC厂家生产HTC手机、HTC电池、诺基亚手机。。。你觉得很奇怪吗, 这个时候就需要抽象工厂模式来解决了,HTC应该生产HTC旗下的产品、苹果生产苹果系列的产品,这样管理起来也方便。 看看代码例子: [cpp] view plain copy #include<iostream> #include<string> #include<vector> using namespace std; class AbstractPruduct { public: AbstractPruduct(){} ~AbstractPruduct(){} virtual void print()=0; }; class ProductA:public AbstractPruduct { public: ProductA(){cout<<"

C++数组指针、指针数组、函数指针的核心概念

1.什么叫数组指针? 数组指针:一个指向一维或者多维数组的指针。 比如:int * b=new int[10];指向一维数组的指针b ; 注意,这个时候释放空间一定要delete [] ,否则会造成内存泄露,b 就成为了空悬指针。 int (*b2)[10]=new int[10][10]; 注意,这里的b2指向了一个二维int型数组的首地址。 注意:在这里,b2等效于二维数组名,但没有指出其边界,即最高维的元素数量,但是它的最低维数的元素数量必须要指定!就像指向字符的指针,即等效一个字符串,不要把指向字符的指针说成指向字符串的指针。这与数组的嵌套定义相一致。 int(*b3) [30] [20]; //三级指针――>指向三维数组的指针; int (*b2) [20]; //二级指针; b3=new int [1] [20] [30]; b2=new int [30] [20]; 两个数组都是由600个整数组成,前者是只有一个元素的三维数组,每个元素为30行20列的二维数组,而另一个是有30个元素的二维数组,每个元素为20个元素的一维数组。 删除这两个动态数组可用下式: delete [] b3; //删除(释放)三维数组; delete [] b2; //删除(释放)二维数组; 再次重申:这里的b2的类型是int (*) ,这样表示一个指向二维数组的指针。b3表示一个指向(指向二维数组的指针)的指针,也就是三级指针. 2.什么叫指针数组? 指针数组:一个数组里存放的都是同一个类型的指针,通常我们把他叫做指针数组。 比如 int * a[10];它里边放了10个int * 型变量,由于它是一个数组,已经在栈区分配了10个(int * )的空间,也就是32位机上是40个byte,每个空间都可以存放一个int型变量的地址,这个时候你可以为这个数组的每一个元素初始化,或者单独做个循环去初始化它。 举例:声明一个指针数组如下所示,可理解为:首先,其为一个3维数组,数组里存放的是返回int型的指针。 [cpp] view plain copy int *p[3]; p[0] = new int[4]; p[1] = new int[5]; p[2] = new int[6]; delete p[0]; delete p[1]; delete p[2]; 3.

Linux操作系统单网卡双IP的设置

Centos5下: 1、配置第一个IP地址: [root@Linux root]#cd /etc/sysconfig/network-scripts [root@Linux network-scripts]#vi ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.80.255 //*广播地址*// IPADDR=192.168.80.189 //*第一个IP地址*// NETMASK=255.255.255.0 //*网络掩码*// NETWORK=192.168.80.0 //*所在网段*// ONBOOT=yes :wq //*保存退出*// 2、复制第一个IP地址配置文件为第二个IP地址配置文件,并修改里面的IP地址: [root@Linux network-scripts]#cp ifcfg-eth0 ifcfg-eth1 [root@Linux network-scripts]#vi ifcfg-eth1 DEVICE=eth0:1 //用eth0也可以,也能通,但是重启网卡时会提示eth0 file existed! BOOTPROTO=static BROADCAST=192.168.80.255 //*广播地址*// IPADDR=192.168.80.199 //*第二个IP地址*// NETMASK=255.255.255.0 //*网络掩码*// NETWORK=192.168.80.0 //*所在网段*// ONBOOT=yes :wq //*保存退出*// 3、重启网卡: [root@Linux network-scripts]#service network restart 或: [root@Linux network-scripts]#ifdown eth0 [root@Linux network-scripts]#ifup eth0 或 [root@Linux network-scripts]#ifconfig eth0 down [root@Linux network-scripts]#ifconfig eth0 up 方法二:在配置第二个IP地址的时候有变化其他 1、配置第一个IP地址以及网关: [root@Linux root]#cd /etc/sysconfig/network-scripts [root@Linux network-scripts]#vi ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static BROADCAST=192.

Golanger Web Framework(框架简单实现了MVC的设计方式)

框架简单实现了MVC的设计方式 Features RoutingControllersTemplatesSessionPlugins 约定的命名规则: Model: 存放在models目录中Controller: 存放在controllers目录中View: 存放在views目录中静态文件放在static目录中 运行方法 安装: 下载go安装包,部署go的编译环境安装相应的扩展包<非必须>执行初步命令 cd [path]/website/helloworld/src chmod +x ./build.sh 编译并执行程序 ./build.sh 打开浏览器访问 根据输出的端口 [port]http://localhost:[port] Golanger目录结构说明 Golanger框架主要实现了MVC模式(三层架构模式)(Model-View-Controller), 它是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller) Golanger约定的命名规则: 控制器(Controller): 存放在controllers目录中, 负责转发请求,对请求进行处理.模型(Model): 存放在models目录中, 程序员编写程序应有的功能(实现算法等等)、数据管理和数据库设计(可以实现具体的功能).视图(View): 存放在views目录中, 界面设计人员进行图形界面设计.静态文件放在static目录中.add-on存放第三方库文件,默认是把GOPATH设置为这个目录. 本文以 samples/applicationTemplate/web/website.zip 项目为例,说说Golanger的目录结构: ~/website <master> tree . └── src // 项目源码目录 ├── add-on // 第三方扩展目录, 默认GOPATH目录 ├── build.bat // windows 平台编译脚本 ├── build.sh // Linux/Mac 平台编译脚本 ├── config // 项目配置信息目录 │ └── site // 项目配置文件,采用json的格式,配置了网站的一些基本信息 ├── controllers // 控制器(Controller)模块, 负责所有业务的请求,转发等业务逻辑 │ ├── 404.

source insight怎样恢复默认界面设置!

郁闷,文件搜索的窗口让我弄没了,界面被我弄乱了,。 最终的想法恢复一下默认就好了。 解决方案有一下几种: 1)快捷键:CTRL+O 2)视图选择,项目窗口打勾就行了 3)这个配置文件保存在 我的文档里面Source Insight\Settings文件夹里面 关闭SI,把settings里边的配置文件删掉,重新打开SI,就恢复默认的全部设置了 4)关闭source insight 在工程文件里应该有1个后缀为 .CF3的文件 直接改名或者删除 重新 打开 .pr 启动source insight 效果图如下:

通过sql语句查询表的列和对应的数据并在jsp页面上显示

<%@ page language="java" import="java.util.*, java.sql.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>动态列</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <body> <form action=""> <textarea name=sql cols=80 rows=10>${param.sql}</textarea><br> <input type=submit value=查询> </form> <c:if test="${!empty param.sql}"> <% Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XFSM", "xfsm", "merit"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(request.getParameter("sql")); if(rs == null) { stmt.

another

DLL注入VC教程 1 新建一个mfc extension dll 这个我想用VC的人都会做的事情吧–!名字叫做mydll 2 点击 文件—新建 选择文件 建立一个Header File文件 我们就暂定他的名字叫做Hook吧 3 在刚才建立的Hook.h的文件中加入复制以下的函数进去 extern “C” LRESULT CALLBACK keybordproc(int code,WPARAM wparam,LPARAM lparam); //钩子处理函数 extern “C” bool WINAPI starthook(DWORD threadID); //启动钩子 extern “C” bool WINAPI stophook();//停止钩子 4 在mydll.CPP的#include “stdafx.h”下面添加 #include “Hook.h” #pragma data_seg(“publicdata”) HHOOK hhook=NULL; HINSTANCE pinstance=NULL; #pragma data_seg() 5 找到DllMain…….在里面初始化 pinstance = hInstance; 6 同时 在mydll.CPP中找到空白的地方 复制下面的代码进去 extern “C” bool WINAPI starthook(DWORD threadID)//打开钩子函数 { hhook=SetWindowsHookEx(WH_GETMESSAGE,keybordproc,pinstance,threadID); if(hhook!=NULL) return true;

policy机制中经典的python用法

由于接触python时间还不长,属于边用边学,在看项目代码的时候,遇到了很多不太懂的python语法,但是我认为这些用法用的实在是好,希望以后自己在写程序时,也能写出这么经典的代码,在这里记录下来这些: 1. 将函数名作为参数传递给另一个模块中的函数使用: def init(): ...... #read_cached_file做的事是读取_POLICY_PATH文件中的数据,和这个文件修改的时间,保存到_POLICY_CACHE字典中, #然后使用_set_rules(data)来解析这些数据,最后返回这些数据。 utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE, reload_func=_set_rules) def _set_rules(data): default_rule = CONF.policy_default_rule policy.set_rules(policy.Rules.load_json(data, default_rule)) 2. 类方法的使用 class Rules(dict): @classmethod def load_json(cls, data, default_rule=None): rules = dict((k, parse_rule(v)) for k, v in jsonutils.loads(data).items()) return cls(rules, default_rule)以前一直弄不清楚类方法和静态方法的区别,都是通过类名去调用,但是现在清楚了,类方法有一个很好的特性,就是它可以在创建类对象之前,做一些初始化的工作,这样创建的对象,比直接调用Rules(),更灵活。 这里还想说一下继承自dict这个特性,通过覆盖父类中的方法,__missing__(),__str__()等定制了一个自己的字典类型,用起来很舒服啊。 3. 解释器的使用 _checks = {} def register(name, func=None): def decorator(func): _checks[name] = func return func if func: return decorator(func) return decorator @register("rule") class RuleCheck(Check): pass @register("role") class RoleCheck(Check): pass 文档在加载的时候,每遇到一个@register()修饰符,就会将被修饰的类添加到_check变量中,简洁方便。

UE 汇编语法高亮文件新版 与 UE 常用技巧

1. 倾情奉献:UE汇编语法高亮文件,支持新版本UE和老版本UE(.uew文件和worldfile.txt文件) 下载地址:https://download.csdn.net/download/yingang2009/4828491 MCU开发,免不了要用到汇编语言,这里提供Holtek , Elan , PIC 三种单片机汇编语言支持文件,并且支持子程序列表显示,大大提高子程序查找速度和视觉美感,是单片机汇编开发者必备的工具,特点: 1.支持汇编语法高亮 2.支持子程序(函数)列表显示 3.支持新版本UE和老版本UE(.uew文件和worldfile.txt文件) 高亮效果图如下: 小技巧:如果你近期只使用一种汇编语言,可以暂时删掉其它不用的语法高亮文件,这样就不需要使用菜单去切换语言,直接双击源文件就可以高亮了。 2. UE常用技巧 (UE常用技巧.doc) 一般MCU的IDE(如Keil)提供的编辑功能实在是太弱了,相比专业的编辑器,就好比步行与坐飞机,感觉是不一样的,但前提是你必须掌握“UE的常用技巧” Tip 1: Alt+C列模式 Tip 2:Ctrl+W 切换自动换行 Tip 3:Ctrl+F2 切换书签 Tip 4:F3 查找 Tip 5:Ctrl+R 替换 1.去掉文本中包含某特定字符串的行 2.删除行尾空格 3.删除空行 4.每行行尾添加分号“;” Tip 6:Ctrl+B 括号匹配 Tip 7:Ctrl+E 整行删除,下行上调 Tip 8:F7 插入当前系统时间 Tip 9:Ctrl+G 转到行/页 Tip 10:Ctrl+0 ~ 9 UE的10个剪贴板 3.UE常用正则表达式 (UE常用正则.xls) 添加字符串行首 添加字符串行尾 删除行尾空白 删除行首空白 删除空白行 删除带指定字符串的行 每行设为固定4个空格开头 每段设为固定4个空格开头 一段合并成一行 删除前两列的字符 匹配所有数字 匹配所有单词 匹配网址

Eclipse Hadoop配置遇到的问题

1. Eclipse "Run on Hadoop"不起作用 当Eclipse版本较高而Hadoop的版本较低时,Run on Hadoop是不行的,需要下载匹配的版本,目前来看hadoop 1.0以上的hadoop.eclipse插件只能用于eclipse 3.6以及3.7以上。 2. Eclipse 中新建了MapReduce DFS之后,无法显示HDFS下的文件,错误原因是“connection refused”,这个错误的原因是因为没有启动Hadoop,启动之后即可解决这个问题, 还需注意的一点是,如果之前已经启动过了,需要HDFS和tmp文件全部删除。 3. 出现连接不上namenode的情况 即“Retrying connect to server”等,这个情况的解决,一是由于之前残余的Hadoop,没有情况,需要将HDFS等文件夹全部删除;二是可以改动conf/文件夹下site文件的端口。

HP1005激光一体机出现Load tray plain ,A4

打印机恢复出厂设置如果不能解决问题,则问题出在设置上: 1、打印首选项-进纸选择是否选成了手动 2、打印页面设置,进纸选择是否选成了手动。 以上选成自动进纸即可。

malloc与free 动态内存的申请与释放

C标准库函数malloc 可以再堆空间中动态分配内存,动态分配的内存用完了之后,可以用free函数释放,更准确的说是归还给了malloc,下次调用malloc时,这块内存可以再次分配出来。 #include<stdlib.h> void *malloc(size_t size); 返回值: 成功返回所分配内存空间的首地址,出错返回null void free(void *ptr); malloc 的参数size表示要分配的字节数,如果分配失败(很可能是因为系统内存耗尽)则返回null。由于malloc函数不知道用户拿到这块内存要存放什么类型的数据,所以返回通用指针void * ,用户可以转换成其他类型的指针再访问这块内存。 malloc函数保证它返回的指针所指向的地址满足系统的对齐要求,例如在32位平台,返回的指针一定对齐到4字节边界,以保证用户程序把它转换成任何类型的指针都能使用。 free可以释放动态分配的内存,传给free的参数正是先前malloc返回的内存块首地址。 unit_t *p = malloc(sizeof(unit_t)); if (p == NULL) { printf("out of memory\n"); exit(1); } ......... free(p); 一定要判断申请内存是否成功!!如果程序长年累月的申请内存(例如,网络服务程序),并且每次都申请内存,分配完了又不释放,就会发现内存慢慢的耗尽。 另外,malloc返回的指针一定要保存好,只有把他传给free才能释放者块内存。如果这个指针丢失了,就没有办法释放这块内存了,就会造成内存泄露。 void foo (void) { char *p = malloc(10); ............ } foo函数返回时要释放局部变量p的内存空间,它所指向的内存地址就会丢失,这10个字节也就没有办法释放了。内存泄露的bug非常难找,因为它并不像访问越界一样导致程序错误,少量内存泄露并不影响程序的正常运行,大量的内存泄露会导致物理内存紧缺,换页频繁,不仅影响当前进程,而且会把整个系统都托的很慢。

使用mod_wsgi部署django

一、配置前说明: 我的django工程名为 sysencrypt该工程所在目录为 /home/web我的django静态文件目录为/home/web/sysencrypt/static 二、配置WSGI文件 在工程目录下创建django.wsgi文件,内容如下 #!/usr/local/bin/python import os import sys path='/home/web/' #change to your path.DON'T foget the last'/' sys.path.append(path) sys.path.append(path+'sysencrypt') os.environ['DJANGO_SETTINGS_MODULE'] = 'sysencrypt.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler() 三、配置httpd.conf 在httpd.conf文件中添加如下内容: WSGIScriptAlias / /home/web/sysencrypt/django.wsgi <Directory "/home/web/sysencrypt/static"> Order deny,allow Allow from all </Directory> <Directory "/home/web/"> AllowOverride All Order deny,allow Allow from all </Directory> Alias /static/ /home/web/sysencrypt/static/ 四、重启apache服务器 service httpd restart

取相关记录集数据

//1 使可以选择对象。 public void SelectPoint() { foreach (Layer currentLayer in m_mapControl.Map.Layers) { Dataset dataset = currentLayer.Dataset; #region //这里必须加dataset!= null 这样可以先判读dataset。 //如果dataset为空。就可以不执行dataset.Name == "EQPoint" //如果不加dataset!=null,如果dataset为空时,执行dataset.Name == "EQPoint"会使程序崩掉 //dataset.Name 要使用对象属性,先要保证对象不为空 #endregion if (dataset != null && dataset.Name == "Point") { currentLayer.IsSelectable = true; } else { currentLayer.IsSelectable = false; } } SetMapAction(Action.Select); //设置为可以选择地图图形对象,select只能点击选择,不能框选 } //2 触发图形对象选择事件,选点----》取点id----》根据点id取有关所有面id---》根据面ID找到 void m_mapControl_GeometrySelected(object sender, GeometrySelectedEventArgs e) { Recordset recordsetSelected = null; //获得选中的点对象。因为设了Acton.select 所以只能选中一个对象 Selection[] arrSelections = m_mapControl.

北理工虚拟现实作业-OpenGL下实现3D Max模型的导入

两个礼拜之前,李凤霞老师又布置了一次虚拟现实作业,这次的作业题目是自己从网上找一个汽车的3D模型(一般都是3D Max建的),然后把这个模型导入到OpenGL中,在工程中显示出来,同时能通过鼠标的移动切换视角。由于时间太紧(矩阵分析要考试),这个作业就拜托了宿舍的一个同学,可是没想到最后还是自己做了,就这样也学了点东西(不过不知道有什么用)。 先贴下实现效果,车辆是网上找的一个奥迪Q7 3D模型,为了简单不再贴纹理了 下面说下实现步骤: 1、转换3D Max模型 3D MAX建模后生成的一般都是3ds后缀的文件,直接导入貌似还要在opengl中建立对应的数据结构,上网查了一些资料后,我发现可以用View3D软件把3DS文件转换成.h和.gl两个文件,然后把这两个文件拷贝到工程目录下http://hi.baidu.com/chyrcpxjpxbcege/item/3fe0cd59f170af3e32e0a919 给出了其他的一些导入方法 2、添加头文件和初始化 把.h文件添加到工程中去后,在.h文件中加入一个新的类用以导入 class CModernho { public: CModernho(void); public: ~CModernho(void); public: long ScanBytes(int pixWidth, int bitsPixel); void MyMaterial(GLenum mode, GLfloat * f, GLfloat alpha); void SelectMaterial(int i); GLint Gen3DObjectList(); }; CModernho::CModernho(void) { } CModernho::~CModernho(void) { } 然后在主文件中添加对应的内容 开头定义一个变量,应该对应导入的数目 int listnum;//导入变量 在main函数中初始化时载入该模型 CModernho cmodernho; listnum = GL3DS_initialize_audi(); //载入audi 最后在渲染函数中调用该模型 glCallList(listnum);// 调用载入函数 这样就得到了以上的效果,工程结构如下: audi.h就是view3d转换后的文件,很长,其中包含很多点线的信息,显然是把模型的各个点和线都保存下来了 testcar.cpp代码如下: #include <gl/glaux.h> #include <gl/glu.h> #include <GL/glut.h> #include "

什么是软件制造工程

软件制造工程实施之前,软件还是一种看不见摸不着的东西。软件制造工程就是要把 系统工程师按照用户的需求设计出来的系统构架(窗体显示和报表式样等)变为真正的可以 运行的软件系统的工程,即是它把软件生存周期过程中的上流工程(需求分析、设计工程) 所产生的结果作为制造工程的输入,而制造工程又是将上一阶段提出的方案进一步具体化 经过程序设计、程序编码、测试,变为真正可以运行的软件产品。 转载于:https://blog.51cto.com/yubooa/1061038

问答——为什么很多 iOS app 存在秒退现象?有什么好的方法避免?

问题里的“秒退”如果我没理解错,应该是指程序显示完默认启动图片后,在初始化阶段就崩溃了(也可以叫“闪退”,不过最近“闪退”这个词已经被广泛应用于各种程序崩溃情况了,所以可能还是“秒退”更准确?)。 这种情况应和所谓的内存不足关系不大,很少有程序会在初始化时载入大量内容导致崩溃,并且这类问题也很容易在开发阶段被发现,所以内存不足造成秒退的可能性低(内存不足退,通常是程序用了一段时间,切换了几个画面以后发生的)。 而且秒退是发生在程序刚刚启动的时候,在开发、苹果审核阶段都没有被发现的最大可能性就是,这个问题只会发生在老版系统、老版机型上。 对于很多开发者(尤其是个人开发者),进行所有 iOS 版本,所有 iOS 机型覆盖测试是有难度的,苹果审核时也只是重点审核该应用在新机器、新版本下的运行情况,并不关注老系统。所以这也就是为什么会秒退的程序竟然也能通过苹果的审核。 在新 iOS 上正常的应用,到了老版本 iOS 上秒退最常见原因是系统动态链接库或Framework无法找到。这种情况通常是由于 App 引用了一个新版操作系统里的动态库(或者某动态库的新版本)或只有新 iOS 支持的 Framework,而又没有对老系统进行测试,于是当 App 运行在老系统上时便由于找不到而秒退。解决办法是等开发人员发现这个问题后升级程序,或由用户自行升级其操作系统。 还有一种常见的秒退是程序在升级时,修改了本地存储的数据结构,但是对用户既存的旧数据没有做好升级,结果导致初始化时因为无法正确读取用户数据而秒退。这类问题通常只需删除程序后重新安装一遍就能解决。但缺点是用户的既存数据会丢失——就算有备份可能也无济于事,因为备份下来的旧数据还是无法被正确升级。如果旧数据非常重要,那么就需要联系开发人员要求其进行程序修正了。 另一种已经变得不那么常见的秒退原因是 App 的设置不正确。例如在编译时没有编译 ARMv6 的版本,但是设置里却允许该 App 运行在 ARMv6 处理器的机器上(如:iPhone 1代,iPhone 3G,iPod touch 1、2代和3代8G版)。这个问题除了等开发人员升级外用户自己没什么办法解决。当然愿意换台新机器是最好的 ;) 这个问题目前已经能够在提交应用至 App Store 的时候被检查出来了,因此今后应该不太常见了。 还有一类秒退或是用到 App 里某个功能后必退的原因,是开发时用到了只有新版操作系统才支持的某个方法,而又没有对该方法是否存在于老系统中做出判断。例如程序启动时用到了 Game Center,而没有判断用户的机器是否支持 Game Center,于是就秒退了。 主要的秒退情况就是这么几个,这些都是以该 App 新版系统上能正常跑为前提的。 诸如内存不足、BAD_ACCESS 这类问题通常不管在新旧 iOS 上都会存在,如果是由于这类问题造成的秒退通常都能在测试和审核阶段被发现,因此并不常见。

jquery.ui.datepicker 添加时分秒

jquery.ui 的 datepicker 默认是年月日的jquery 插件,如果添加时分秒 只需要做如下修改即可 1. 下载jquery-ui-timepicker-addon.js ,并在页面加载 2. 页面添加如下 timepicker 的样式即可 .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } .ui-timepicker-div dl { text-align: left; } .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } .ui-timepicker-div td { font-size: 90%; } .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } 3. js 中 设置某input 的时间格式 <input type="text" id="datetime" name="

寄存器与缓存的区别

这里的缓存是指的CPU的缓存。 按与CPU远近来分,离得最近的是寄存器,然后缓存,最后内存。 所以,寄存器是最贴近CPU的,而且CPU只与寄存器中进行存取。 (寄存的意思是,暂时存放数据,不中每次从内存中取,它就是一个临时放数据的空间,火车站寄存处就是这个意思) 而寄存器的数据又来源于内存。于是 CPU<--->寄存器<----->内存 这就是它们之间的信息交换。 那为什么有缓存呢? 因为如果老是操作内存中的同一址地的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存。 缓存就把从内存提取的数据暂时保存在里面,如果寄存器要取内存中同一位置的东西,就不用老远巴巴地跑 到内存中去取,直接从缓存中提取。 因为从缓存提取的速度远高于内存。当然缓存的价格肯定远远高于内存,不然的话,机器里就没有内存的存在, 只有缓存的存在了,但如果全是缓存,相信没有几个人买 得起计算机了。 由此可以看出,从远近来看: CPU〈------〉寄存器〈---->缓存<----->内存 注意一下,寄存器并不每次数据都可以从缓存中取得数据,万一不是同一个内存地址中的数据,那寄存器还必须 直接绕过缓存从内存中取数据。所以并不每次都得到缓存中取数据,这就是缓存的命中率,从缓存中取就命中,不从 缓存中取从内存中取,就没命中。当然关于缓存命中率又是一门学问,哪些留在缓存中,哪些不留在缓存中,都是命中 的算法。 从经济和速度的综合考虑,又有了一级缓存和二级缓存,当然一级缓存价格远高于二级缓存,它们的作用类似,但速度上 一级缓存速度明显高于二级缓存,因为价格的原因就设置了二级缓存,也不知道将来 会不会能三级缓存呢?

ubuntu chrome 启用java

32-bit Oracle Java instructions: 1 Issue the following commands. Type/Copy/Paste: sudo -s this will change you into root Type/Copy/Paste: mkdir -p /opt/google/chrome/plugins this will create a directory called /opt/google/chrome/plugins Type/Paste/Copy: cd /opt/google/chrome/plugins this will change you into the google chrome plugins directory,make sure you are in this directory before you make the symbolic link Type/Paste/Copy: ln -s /usr/local/java/jre1.7.0_09/lib/i386/libnpjp2.so this will create a symbolic link from the Java JRE( Java Runtime Environment ) plugin libnpjp2.

VBA宏实现将中文转为拼音(转帖+亲自实践)

以下内容来自百度文库 将写在A1单元格的中文,转化为拼音写在B1单元格 缺点是:针对中文中的多音字,无法识别。 Sub 按钮1_Click() Cells(1, 2).Value = PinYin(Cells(1, 1).Value) End Sub Public Function PinYin(Hz As String) Dim PinMa As String Dim MyPinMa As Variant Dim Temp As Integer, i As Integer, j As Integer PinMa = "a,20319,ai,20317,an,20304,ang,20295,ao,20292," PinMa = PinMa & "ba,20283,bai,20265,ban,20257,bang,20242,bao,20230,bei,20051,ben,20036,beng,20032,bi,20026,bian,20002,biao,19990,bie,19986,bin,19982,bing,19976,bo,19805,bu,19784," PinMa = PinMa & "ca,19775,cai,19774,can,19763,cang,19756,cao,19751,ce,19746,ceng,19741,cha,19739,chai,19728,chan,19725,chang,19715,chao,19540,che,19531,chen,19525,cheng,19515,chi,19500,chong,19484,chou,19479,chu,19467,chuai,19289,chuan,19288,chuang,19281,chui,19275,chun,19270,chuo,19263,ci,19261,cong,19249,cou,19243,cu,19242,cuan,19238,cui,19235,cun,19227,cuo,19224," PinMa = PinMa & "da,19218,dai,19212,dan,19038,dang,19023,dao,19018,de,19006,deng,19003,di,18996,dian,18977,diao,18961,die,18952,ding,18783,diu,18774,dong,18773,dou,18763,du,18756,duan,18741,dui,18735,dun,18731,duo,18722," PinMa = PinMa & "e,18710,en,18697,er,18696," PinMa = PinMa & "fa,18526,fan,18518,fang,18501,fei,18490,fen,18478,feng,18463,fo,18448,fou,18447,fu,18446," PinMa = PinMa & "ga,18239,gai,18237,gan,18231,gang,18220,gao,18211,ge,18201,gei,18184,gen,18183,geng,18181,gong,18012,gou,17997,gu,17988,gua,17970,guai,17964,guan,17961,guang,17950,gui,17947,gun,17931,guo,17928," PinMa = PinMa & "

set -o vi

et -o vi再用esc+K键就可以使用上一条指令了 esc+k esc+j 上下翻 ksh默认是emacs风格的。set -o emacs 【提示】:多试试F1--F11,你 会有意想不到的收获哦! 在AIX下使用自己已经使用过的命令 在AIX下使用,默认的shell是KSH,和linux下的bash不一样的是,他不能采用我们大家已经熟悉的DOS下的键或者其他我们已经熟悉的快捷键来使用我们上次已经使用过的命令,比如在DOS命令状态下(我把我自己经常用的快捷键列出来,可能还其他的,慢慢补充),大家可以通过F7来取得你已经在当前DOS窗口中输入过的不重复的命令(Windows对你自己在当前窗口顺序输入的非重复命令进行排序,以0,1,2...来编号),F1重复上次同一个位置上的字符,F3重复上次所有的命令,F5和F8向上翻我已经输入过的命令,F9是可以输入你要显示的上次输入的非重复的命令ID(比如,进入某DOS窗口之后,我依次输入了两条命令:dir和cd test,那么本窗口的第0条命令就是dir,类推,当我按下F9的时候,系统提示我“输入命令号码”,这个时候我按照上次输入的顺序号进行输入即可,比如选择0那么这个时候就是dir命令,这个功能和F7的功能是一致的,只是F7可以选择,F9可以直接输入,这两个功能当你输入的命令比较长的时候是比较有用的)。 要想在AIX下使用上次你已经使用过的命令,可以使用以下的方法: 1、在ksh下,运行set -o vi,这个时候整个命令状态就是是VI编辑器了,操作的方法和VI编辑器一摸一样,要重复上次的命令,就在当前状态栏下按ESC,然后输入k,就可以看到下一条命令,按下k就可以查询上一条命令,h可以在当前行向前移动一个字符的位置,l可以在当前行向后移动一个字符的为止,当然这个时候相当于处于vi的状态,所有在vi状态下的对单行操作的命令都可以使用。编辑好之后直接按回车即可。 2、如果不不是在ksh下,那么你可以在命令窗口下运行ksh -o vi,其他的命令和第一种方法一样 3、在ksh的环境变量中设置EDITOR=vi即可,修改的方法即在.profile中直接加入EDITOR=vi;export EDITOR即可。 4、删除历史命令,可以在当前用户的主目录下,查询到一个.sh_history的文件,里面记载了你所有在当前用户输入过的命令。可以将这个文件编辑一下,然后将其中的命令删除掉就可以了。当然你可以将自己喜欢的命令或者比较长的命令放在里面,以后你就直接调用就可以了。当然从这个文件可以看出上面几点讲的采用vi的命令来取得上次的命令,其实ksh是取得这个文件中的信息。 5、以下小技巧: a、重复上一条命令可以直接在ksh状态下输入r b、你可以在ksh状态下执行r a=b,意思是先将上一条命令中的a字符用b字符替换,然后运行。 原因后来上网查了一下,暂且引用一下《FreeBSD使用大全》中的一段内容: ----------------------------------------------------------------------------------------------- 配置用戶shell 事實上sh與csh,并不是普通用戶的最佳選擇,因為這兩個shell在易用性方面做的不夠好,例如命令行編 輯功能不強、不能利用熱鍵重復執行命令等。較新的shell,如bash和tcsh都具有這些方便用戶使用的功能,但 必須安裝了這些shell程序之后,才能更改普通用戶的shell設置以使用這些shell程序。更改用戶的shell 可以使用pw、vipw或chsh。 這兩個shell分別遵照sh和csh的風格,因此喜好csh風格的可以選擇tcsh,而喜歡sh風格的選擇 bash。除了這兩種shell之外,還有ksh、zsh等shell可供選擇。如果對兩種shell沒有偏好,可以 選擇bash,它是一個GNU軟件,比標准sh功能強大的多。 使用了這兩些增強型shell之后,用戶就可以使用shell提供的命令行編輯功能。按照習慣的不同,可以選 擇vi風格的編輯方式或emacs風格的方式,缺省為emacs方式,這種方式使用方向鍵來回溯執行過的命令,并進行 修改,而vi風格使用字母命令作編輯鍵,例如使用h、j、k、l四個鍵來移動光標,vi風格的好處是不使用基本鍵盤之 外的控制鍵,因而可以適用于任何終端設備,并且進行編輯時手不需離開基本鍵盤,熟練操作之后最為快捷。emacs風格 比起vi風格更適合從個人計算機轉向Unix的使用者的習慣。bash, ksh ,zsh下使用下面的命令在emacs 風格和vi風格切換: bash$ set -o emacs bash$ set -o vi tcsh中使用不同的命令: % bind emacs % bind vi 還可以為常用的命令設置別名,簡化用戶輸入,例如: bash$ alias ec=”echo This is a alias”

iOS直接获取摄像头数据

需要添加的 Framework :CoreMedia, CoreVideo QuartzCore, AVFoundation MyAVController.h: #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> #import <CoreGraphics/CoreGraphics.h> #import <CoreVideo/CoreVideo.h> #import <CoreMedia/CoreMedia.h> @interface MyAVController : UIViewController < AVCaptureVideoDataOutputSampleBufferDelegate> { AVCaptureSession *_captureSession; UIImageView *_imageView; CALayer *_customLayer; AVCaptureVideoPreviewLayer *_prevLayer; } @property (nonatomic, retain) AVCaptureSession *captureSession; @property (nonatomic, retain) UIImageView *imageView; @property (nonatomic, retain) CALayer *customLayer; @property (nonatomic, retain) AVCaptureVideoPreviewLayer *prevLayer; - (void)initCapture; @end MyAVController.m: #import "MyAVController.h" @implementation MyAVController @synthesize captureSession = _captureSession; @synthesize imageView = _imageView; @synthesize customLayer = _customLayer; @synthesize prevLayer = _prevLayer; #pragma mark - #pragma mark Initialization - (id)init { self = [super init]; if (self) { self.

mysql 去掉换行符,回车符

1 去掉回车+换行 update test set logiccontent=replace(logiccontent, char(13)+char(10), ''); 2去掉回车 update test set logiccontent=replace(logiccontent, char(13), ''); 3去掉换行 update test set logiccontent=replace(logiccontent, char(10), ''); 4查询含有'%'的字串 SELECT DISTINCT key_word FROM dim_ec_ref WHERE key_word LIKE '%/%%%' ESCAPE '/'

FML32 API

FML32 API 索引:1.概述 2.域表文件 3.域头文件 4.mkfldhdr(32)工具 5.环境变量 6.Falloc(Falloc32) 7.Fsizeof(Fsizeof32) 8.Fneeded(Fneeded32) 9.Finit(Finit32) 10.Fadd(Fadd32) 11.Fchg(Fchg32) 12.Fget(Fget32) 13.Fcpy(Fcpy32) 14.输入/输出函数 15.Fvftos(Fvftos32) 16.Fvstof(Fvstof32) 1.概述基本概念Field Manipulation Language (FML)或(FML32)可以定义多个有名字的域,它是一张属性和值的表。 支持的域数据类型有:short、char、long、float、double、string、carray。 FML(FML32)buffer通过一套API来管理,大约有60多个函数接口。 FML有较强大的功能,使用也很灵活。缺点是接口较复杂,有很多的处理函数,而且使用效率较VIEW等要慢。 FML的基本组成部分FML buffer的域通过域ID(数字)来访问。处理FML buffer至少需要如下四个部分: 域表文件。提供名字-数字映射; 域头文件。提供C程序一些生成的宏而不是数字来访问域; 环境变量FIELDTBLS(32)和FLDTBLDIR(32)定位表文件; C语言接口: 库:libfml.a和libfml32.a; 头文件:fml.h和fml32.h; 处理16位到32位转换代码:fml1632.h。 FML buffer的结构一个域buffer有三部分组成:buffer头部、数据域和索引项。 处理FML的流程定义所有的域名字、对应的数据类型和数字标识。数字标识100以下为系统保留,对16位buffer,数字标识的范围是100-8191,32位buffer是100-33,554,431。 根据这些定义编辑一个域表文件。 使用mkfldhdr(32)生成域头文件。 编译应用程序,使用生成的头文件和fml.h(fml32.h),链接libfml.a(libfml32.a)。 正确设置环境变量FIELDTBLS(32)和FLDTBLDIR(32)。 2.域表文件文件形式如下: *base 100 # name number type flags comments ACCOUNT_ID 10 long - - ACCT_TYPE 11 char - - ADDRESS 09 string - - AMOUNT 16 float - - 文件中以#开头的行被忽略。

linux后台运行命令

后台运行脚本 monitor.sh & --shell终端断掉脚本就停止运行了 nohup command & --不挂断的执行程序 setsid command & --关闭shell终端,命令继续后台运行 (monitor.sh &) --关闭shell终端,命令继续后台运行 disown -h %1 开机执行脚本 方案一: 1.因为其中的rc.local是在完成所有初始化之后执行,因此我们可以把启动脚本写到里面 2.用root账号登陆Linux,vi /etc/rc.d/rc.local编辑文件,在最后加入两行需要执行的脚本程序 cd /home/test1 --该步不可少,否则会提示没有权限打开'test.log'文件 su test1 -c "python /home/test1/test.py" --把要执行的命令作为一个参数传递级su 方案二: 1.init.d目录下都为可执行程序,他们其实是服务脚本,按照一定格式编写,Linux 在启动时会自动执行,类似Windows下 的服务 2.用root帐号登录,vi /etc/rc.d/init.d/mystart,追加如下内容: #!/bin/bash #chkconfig:2345 80 05 --指定在哪几个级别执行,0一般指关机, 6指的是重启,其他为正常启动。80为启动的优先级,05为关闭的优先机 #description:mystart service RETVAL=0 start(){ --启动服务的入口函数 echo -n "mystart serive ..." cd /home/test1 su test1 -c "python /home/test1/test.py" } stop(){ --关闭服务的入口函数 echo "mystart service is stoped..." } case $1 in --使用case,可以进行交互式操作 start) start ;; stop) stop ;; esac exit $RETVAL 3.

数组 按行,列存储

二维数组 二维数组Amn可视为由m个行向量组成的向量,或由n个列向量组成的向量。 数组的顺序存储方式 由于计算机内存是一维的,多维数组的元素应排成线性序列后存人存储器。 数组一般不做插入和删除操作,即结构中元素个数和元素间关系不变化。一般采用顺序存储方法表示数组。 (1) 行优先顺序 将数组元素按行向量排列,第i+1个行向量紧接在第i个行向量后面。 例: 二维数组Amn的按行优先存储的线性序列为: a11,a12,…,a1n,a21,a22,…,a2n,……,am1,am2,…,amn 注意: PASCAL和C语言中,数组按行优先顺序存储。 行优先顺序推广到多维数组,可规定为先排最右的下标。 (2) 列优先顺序 将数组元素按列向量排列,第i+1个列向量紧接在第i个列向量后面。 例: 二维数组Amn的按列优先存储的线性序列为: a11,a21,…,am1,a12,a22,…,am2,……,a1n,a2n,…,amn 注意: FORTRAN语言中,数组按列优先顺序存储。 列优先顺序推广到多维数组,可规定为先排最左的下标。 数组元素的地址计算公式 (1) 按行优先顺序存储的二维数组Amn地址计算公式 LOC(aij)=LOC(a11)+[(i-1)×n+j-1]×d 其中: LOC(a11)是开始结点的存放地址(即基地址) d为每个元素所占的存储单元数 由地址计算公式可得,数组中任一元素可通过地址公式在相同时间内存取。即顺序存储的数组是随机存取结构。 (2) 按列优先顺序存储的二维数组Amn地址计算公式 LOC(aij)=LOC(a11)+[(j-1)×m+i-1]×d

Tuxedo数据buffer基本类型介绍

Tuxedo数据buffer基本类型介绍 一、 课程目标 通过本课程学习,你可以掌握如下知识: 掌握tuxedo中STRING类型buffer的用途 掌握tuxedo中CARRAY类型buffer的用途 掌握tuxedo中FML(FML32)类型buffer的用途 掌握tuxedo中VIEW(VIEW32)类型buffer的用途 注:后续的课程将介绍Tuxedo新增的数据类型:EFML(Embedded Record in FML)、XML Buffer 二、 String类型buffer介绍 (1)STRING类型buffer简介 STRING类型buffer是主要用于面向行、变长度的文本信息类型buffer。STRING类型buffer要求必须以NULL作为结束符的。如果系统采用STRING类型,那么在配置ubbconfig文件时,必须在*MACHINE部分配置TYPE,指明buffer类型为STRING类型。在两种不同类型架构的机器进行buffer传输时候,TUXEDO对STRING类型buffer进行加码、解码过程。无论系统申请了多少长度的buffer,系统自动按着NULL所在的位置决定STRING类型的buffer长度。 (2)STRING类型buffer如何申请 char *SndBuf; SndBuf = (char *) tpalloc("STRING",NULL,1024) (3)STRING类型使用方法和调用方法 strcpy(SndBuf,"Bea Tuxedo"); tpcall("TOUPPER",SndBuf,0,&RcvBuf,&len,0); 三、 CARRAY类型buffer介绍 (1)CARRAY类型buffer简介 CARRAY类型buffer是一种独立于机器的buffer类型。用户在使用时必须指定CARRAY类型数据的长度,CARRAY类型数据可以包含NULL字符。CARRAY类型数据不需要加、解码过程。CARRAY类型数据可以用来传输汉字、二进制数据、文件、图形等。CARRAY类型可以作为FML(FML32)、VIEW(VIEW32)的数据类型子项buffer。 (2)CARRAY类型buffer如何申请 tpalloc("CARRAY",NULL,1024*2) (3)CARRAY类型使用方法和调用方法 四、 VIEW(VIEW32)类型buffer介绍 (1)VIEW类型buffer简介 Tuxedo使用VIEW类型buffer处理类似C语言的结构等数据类型复杂数据。使用VIEW类型buffer可以将各数据元素与一种结构数据类型结合,通过结构就可以访问各数据元素。VIEW类型数据即使没有没有数据也占用空间,结构发生变化,需要重新编译程序。 注明:(VIEW类型buffer是16位寻址的,VIEW32是32位寻址的.) (2)VIEW类型buffer使用方法 使用VIEW类型数据步骤: 建立VIEW文件 设置环境变量 编译VIEW文件 在代码中包含VIEW头文件,在程序中使用VIEW结构及API函数 编译程序 运行程序 (1)建立VIEW文件 VIEW user $ /* VIEW structure for user information */ #type cname fbname count flag size null long count COUNT 1 - - “” 0

《flex与bison》读书笔记--ch01 flex和bison简介(上)

说起flex,大多数人第一感觉是adobe的 Flex,包括百度、Google也是这么认为,看来Flex确实是热火朝天啊,等有空了也玩下Adobe的Flex。为了不和Adobe的产品混淆,这里统统用flex来指快速文法分析器。 -------------------------------------------------------------- flex和bison是用来生成程序的工具,它们所生成的程序能够处理结构化输入。 词法分析和语法分析 词法分析(lexical analysis,或scanning)把输入分割成一个个有意义的词块,称为记号(token)。用编译原理课本中的话来说,词法分析的过程就是识别单词的过程,输入的是字符串,输出的是单词。 语法分析(syntax analysis,或parsing)确定这些记号是如何彼此关联的。用编译原理课本中的话来说,语法分析的过程就是识别句子的过程,输入的是单词,输出的是句子。 正则表达式和词法分析 词法分析通常所做的就是在输入中寻找字符的模式(pattern)。一种简洁明了的模式描述方式就是正则表达式(regular expression,常简写为regex或regexp)。编辑器ed和vi以及搜索程序grep就是用这种方式来描述其所要查找的文本。flex程序主要由一系列带有指令的正则表达式组成,这些指令确定了正则表达式匹配后响应的动作(action)。由flex生成的词法分析器可以读取输入,匹配输入与所有的正则表达式并且执行每次匹配后适当的关联动作。flex会把所有的正则表达式翻译成一种高效的内部格式,这使它几乎可以同时处理所有需要匹配的模式,因此它的速度可以成百倍地提高。这种内部格式使用确定性有穷自动机(DeterministicFiniteAutomation,DFA)。对于DFA,他们的处理速度与模式的个数和复杂度无关。 /* wc程序 */ %{ int chars = 0; int words = 0; int lines = 0; }% %% [a-zA-Z]+ { words++; chars += strlen(yytext);} \n { chars++; lines++;} . { chars++;} %% main(int argc, char **argv) { yylex(); printf("%8d%8d%8d\n", lines, words, chars); } flex程序包含3个部分,各部分之间通过仅有%%的行来分割。 第1部分:包含声明和选项设置。在这部分,%{和}%之间的代码会被原样照抄到生成的C文件的开头部分。在这个例子里面,它只是用来设定了行数、单词数和字符数的变量。 第2部分:一系列的模式和动作。这部分中,每个模式处在一行的开头处,接着是模式匹配时所需要执行的C代码。这儿的C代码使用{}括住的一行或者多行语句。(模式必须在行首出现,因为flex认为以空白开始的行都是代码而把它们照抄到生成的C程序中。) 第3部分:会被拷贝到生成的词法分析器里面的C代码,它们一般是一些与动作代码相关的例程。这个主程序负责调用flex提供的词法分析例程yylex(),并输出结果。在没有任何其他改变的情况下,词法分析器将读取标准输入。 将上面的代码存为wc.l并执行:flex -o wc.c wc.l 后生成wc.c文件,其内容如下: #line 2 "wc.c" #line 4 "

最长单调子序列

最长单调子序列 1. 问题描述(HDU 1160) 给出一些老鼠的质量和速度, 求一串数据证明老鼠的质量和速度成反比例关系? 2. 算法介绍 首先排序(由小到大), 第一关键字“质量”, 第二关键字“速度“ 最长单调子序列方法: Len(i)表示使证明成立的某串数据最后一只老鼠是第 i 只老鼠的该串长度。 对于第i + 1 只老鼠, Len(i + 1)= max (Len (j) + 1, Len(i + 1)) 且 满足速度和质量成反比例关系。 对于 HDU 1160 , 还需求出具体是哪些老鼠, 用一个数组记录上一个老鼠, 递归输出即可。 3. 简单应用 HDU 1421 搬寝室 按重量排序,相邻的两个物品所产生的疲劳度最小。 dp[i][j] 表示i个物品中取j对物品的最低疲劳度 如果j对物品中包含i物品,dp[i][j] = dp[i - 2][j - 1] + i物品 与 i - 1 物品的差的平方; 如果不包含, dp[i][j] = dp[i - 1][j]; HDU 1069 monkey and banana

DP -- 最大连续子段和

最大连续子段和 (HDU 1003) 1.问题描述 给定一串整数, 例如 6 -1 5 4 -7, 求最大连续子段和? 2.算法介绍 此题不能暴力, O(n^2)的时间复杂度必然超时。 考虑如下算法: 设Mi表示前i个整数包含第i个整数的最大连续子段和。 sum (i, j) 表示第i个整数到第j个整数的和, 最大连续子段和就是max sum (i, j), 也就是max Mi; 情况一: 如果M(i-1) <= 0, 则 Mi = 第i个整数 情况二: 如果M(i - 1) > 0, 则 Mi = M(i - 1) + 第i个整数 以上两种情况, 不管第i个整数如何都成立。 所以, 可以在O(n)的时间内求出所有的Mi, 记录最大Mi即为所求的最大连续子段和。 在杭电上的1003题, 还需要计算出最大连续子段的始末位置。 起始位置只在一种情况下被改变, 就是当某个Mi <= 0, 并且之后的某个Mj > max Mi; 3. 源代码 #include <stdio.h> int main() { int i; int T, N; int count, temp; int max, start, end; int number, sum; scanf ("

DP(1) --- 数塔

数塔问题 1. 基本模型 (HDU 2084) 如上图所示数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 数塔思想:自顶向下分析,自底向上计算。 H(i) 表示第i层的最大值。要得到H(i + 1),则考虑上一层结点,到其相邻节点可取得的值,取最大值作为H(i + 1)。 如果按照上述做法,从顶到底算起,则时间复杂度为 O(2^(n – 1)); 考虑从底部算起,计算每个结点到底层的最大值,即上一层结点与其相邻节点的最大值,以这个最大值作为上一层结点的值,重复这一过程,直到塔顶。时间复杂度为O(n) 2. 简单应用 a. 多少条路径 (HDU 2151) 猴子爬树,最初猴子在第一棵树上,每过一分钟,猴子会跳到相邻的树上。现在这里有n棵树,求过了m分钟,有多少种不同的跳法跳到第T棵树。(HDU2151)考虑以下 图形, 是不是很像一个数塔? b. 多顶点型数塔(例题 HDU 1176) 免费馅饼,有0—10个位置,起始时,人在5处,每一秒都会有几个馅饼落下来,每秒人可以移动到相邻的位置,问最多可以接多少个馅饼?考虑如下算法: dp[i][j] 表示从第i秒起第j个位置可得到的馅饼; pie[i][j] 表示第i秒第j个位置落下的馅饼 从最后一秒算起,dp[i][j] = max(dp[i + 1][j], max(dp[i + 1][j - 1], dp[i + 1][j + 1]))+ pie[i][j] 重复这一过程知道t = 0;最后这会形成一个多顶点的数塔,每个位置都是一个顶点。 3. 例题代码 HDU 2084 #include <stdio.h> int tower[100][100]; int main() { int i, j; int T, N; int v1, v2; scanf ("

oracle 创建数据库实例

Oracle数据库实例的创建、删除、修改 以SUSE10SP2、Oracle10gR2为例。 本文中的数据库实例这一称谓应该换做数据库更为准确,数据库可以理解为是一个物理的静态概念,主要包括一些物理存在的数据库文件,而数据库实例则是一个动态概念,包括一些内存区域以及若干进程,数据库实例是对数据库进行操作的执行者。(20090714修改) 安装完Oracle数据库系统的安装后,需要创建数据库实例才能真正开始使用Oracle数据库服务。 总结起来,Oracle有三种创建数据库实例的方法。 第一种,最常用也最简单,那就是通过DBCA(Database Configuration Assistant),这是Oralce提供的一个图形界面的数据库实例配置工具,通过它可以创建、删除和修改数据库实例,它的使用也比较简单、易懂,交互式的图形界面操作,非常准确有效的提示与配置,是一个比较方便的创建数据库实例的方式。 按照DBCA给出的提示,很容易创建一个新数据库实例。 在创建数据库的时候,DBCA还提供了两个选项,让你可以根据刚刚设置好的参数生成一个数据库实例模板和一份数据库实例创建脚本。这两个东西是非常好,非常有用的东西,数据库模板由Oracle自己管理维护,已经创建好的数据库实例模板可以在DBCA图形程序新建数据库实例时作为模板来使用,另外在DBCA使用responseFile文件或者命令行参数创建数据库时也需要用到(见后面介绍);数据库创建脚本是一组脚本,包括shell脚本和sql脚本,这些脚本共同实现一个功能,那就是按照你之前在DBCA中设置好的那样创建一个数据库实例(后面也会有介绍),你需要做的只是将这些脚本在你的代码中调用起来。当然,你也可以选择只生成数据库模板或者数据库脚本,而不用去创建一个真的数据库(这通常很费时间)。 DBCA是一个非常强大的工具,上面看到的只是DBCA最常用的创建一个数据库实例的使用,其实DBCA还提供另外两种使用方法,分别是responseFile和命令行带参调用。 先说DBCA的responseFile使用方法,responseFile这个东东并不陌生,前文讲的Oracle自动安装就是使用responseFile完成的,DBCA的responseFile使用方法和Oracle安装程序的responseFile使用方法基本一致。但DBCA的responseFile的来源只能是Oracle安装包中提供的模板文件,而不能向Oracle安装程序的responseFile一样,先自己record一个,然后再用这个record去指导Oracle的自动安装。从Oracle安装包中获取到DBCA的responseFile模板文件后,你可以根据自己的需要编辑修改该模板文件,以完成对数据库实例的某些参数设置(DBCA图形界面所提供的参数设置,responseFile中都可以设置,而且该responseFile模板文件的注释写的很好,你完全不用担心无法搞定那些繁杂的数据库实例参数设置,赞Oralce一个!)。该模板文件在Oracle安装包中的位置一般在${ORACLE_PACKAGE}/response目录下。 有了responseFile之后,你只需在调用DBCA的时候指定responseFile的位置和另外一些参数: dbca [-silent|-progressOnly] -responseFile responseFile名称 其中-silent|-progressOnly选项意义和Oracle安装程序命令行参数中的同名选项一样,表示完全字符界面自动安装或者带图形提示界面的半自动化安装。 responseFile名称当然就是responseFile的具体位置了。 但是,有一点不是很好,那就是使用DBCA的responseFile方式创建Oracle数据库实例,需要事先已经存在一个数据库实例模板了,在responseFile中再指定该数据库实例模板名,然后DBCA再依据这个已有的数据库实例模板完成新数据库实例的创建,所以就会有前面讲到的DBCA图形界面创建数据库实例时提供生成数据库实例模板的选项(数据库实例模板也可以从一个已有数据库实例生成),就是在这要用到的。 从上面调用DBCA使用responseFile的命令中,应该已经看到了DBCA是提供一些命令行参数选项的,其实DBCA提供的命令行参数选项远比你想象的强大,甚至可以这么说,所有DBCA图形界面和responseFile能够办到的事,通过DBCA丰富的命令行参数选项都可以办到。你在DBCA图形界面上设置的参数或者在responseFile中指定的参数值都可以通过DBCA的命令行参数选项来进行设置,所以你完全可以只通过DBCA的命令行带参调用来完成一个数据库实例的创建(当然也包括删除、修改数据库实例等所有DBCA图形界面所能提供的功能)。其实,我更愿意这样认为,DBCA的responseFile应用也是一种DBCA命令行带参调用的使用。需要注意的是,当DBCA的命令行参数和responseFile同时设置一个参数时,命令行参数的优先级是比responseFile要高的。另外,使用DBCA命令行带参调用新建数据库实例和使用responseFile新建数据库实例一样,也是需要事先已经存在一个数据库实例模板,才能完成新数据库实例的创建。一份非常详细的DBCA所有命令行参数选项列表,你可以通过执行dbca -help获得。 到现在你可能已经发现,DBCA图形界面、DBCA的responseFile使用以及DBCA的命令行带参调用,其实是三个分别具备完全数据库实例设置功能的工具或者接口,分别对应不同的应用场景,它们可以满足你几乎所有的应用需求(使用这样的工具来帮助构建自己的软件真是非常惬意的一件事情,再赞Oracle一个!)。 第二种是通过脚本(是否称为命令行方式更合适,下文描述的脚本方式其实都是命令行方式的非交互式方法,或者说命令行的自动化方式,但其实所有脚本方式都可以将shell脚本或sql脚本中的shell命令、sqlplus命令拆分出来,手工在shell中或者sqlplus界面中进行交互式的输入执行,这可以称为命令行的手工方式)来完成数据库实例的代码中自动创建。这里说的脚本包括shell脚本和sql脚本,这种方式可以说是最适合与编程结合的,因为这些shell脚本或者sql脚本都可以直接在shell命令中调用执行,所以可以很好与shell编程相结合。而这其实是基于一个非常重要的事实,即Oracle提供了一个交互式的命令行工具sqlplus(类似与DB2的db2cmd),这个工具可以认为是一个Oracle数据库管理工具,通过它可以执行一些Oracle的数据库管理命令,来完成一些数据库管理工作(这当然就包括数据库实例的创建),同时你也可以把它当作一个SQL语句执行器,直接在里边执行你想要执行的SQL语句或者存储过程等,并获取执行结果。并且,更重要的是,sqlplus可以直接在shell命令行中进行非交互式的调用执行(通常是调用执行一段sqlplus语句,或者是一个由一些sqlplus语句组成的sql脚本,我所说的sqlplus语句包括Oracle数据库管理维护命令、SQL语句和存储过程等),这就为在shell编程中使用sqlplus完成数据库实例自动创建工作提供了可能。 shell命令行中非交互式调用sqlplus执行一段sqlplus语句是利用shell编程中重定向命令的一个特性,即分隔符重定向输入。一般用法如下: command<<任意自定义分隔符 >(换行)内容 >(换行)内容 >自定义分隔符 shell中遇到<<则会自动将下一个单词认作分隔符,并将分隔符后面的文本当作command命令执行的内容传递给command依次全部执行直至遇到下一个分隔符单词才结束。这里的分隔符可以是任意自定义的单词,通常使用EOF,举例: sqlplus / as sysdba<<EOF startup nomount; select * from v$version; shutdown immediate; exit; EOF 这段shell程序调用sqlplus执行了若干sqlplus语句,用来启动数据库实例,查询数据库版本信息,然后关闭数据库实例,退出sqlplus。 shell命令行中非交互式调用sqlplus执行一个sql脚本是利用sqlplus本身提供的命令行参数。在sqlplus界面中可以通过start命令和@命令来执行一个sql脚本,两者功效相同,用法如下: SQL>start sql脚本绝对路径; SQL>@sql脚本绝对路径; 而在shell命令行中可以使用@来完成sqlplus对sql脚本的调用执行,举例: sqlplus / as sysdba @./MySQL.sql 以上命令会调用sqlplus执行当前目录下的MySQL.sql脚本。 使用脚本来完成数据库实例的创建工作,也分为两种情况。 一种是诚如前文所述的那样,在使用DBCA图形工具创建数据库实例的同时生成一份数据库实例创建脚本(包括若干shell脚本和sql脚本),那么你就可以使用这份脚本,在shell中进行调用,完成数据库实例的代码自动创建。使用这份数据库实例创建脚本创建的新数据库实例和原数据库实例是完全一样,当然,你可以将生成的脚本进行修改,以完成你对数据库实例的某些设置,但是请在你对脚本内容已经足够了解,并且知道你自己在干什么的情况下修改脚本,否则你很有可能使用修改后的脚本无法正确创建数据库实例。这种方法中shell脚本对sqlplus的使用,更多的是使用sqlplus来执行一些Oracle生成的sql脚本(这些sql脚本的内容是就是一些sqlplus语句的集合,它们的任务就是完成数据库实例的创建以及设置)。 另一种情况则是不依靠DBCA生成的脚本,完全由自己来编写实现一份shell脚本,在脚本中你可以调用sqlplus执行一段sqlplus语句或者其它一些sql脚本,以完成数据库实例的创建和设置,这完全取决于你的实现;而最常用的用来创建数据库实例的一个方法就是在sqlplus中使用create database语句,create database语句提供了许多丰富的选项和参数设置,确保你能完全创建一个自己所需要的数据库实例。当然,还有一些其它方法可以创建数据库实例,比如调用执行oracle提供某些存储过程等。 至于create database语句的详细介绍可以参考oracle的sql reference。 第三种严格来说不能算作一种创建Oracle数据库实例的方法,它是通过已有的数据库实例为基础来完成新数据库实例的创建的。这种方法是首先通过第一种或者第二种方法来创建好一个数据库实例,然后将该数据库实例的物理文件进行备份,然后直接使用备份的物理文件恢复出一个与原数据库实例完全一样新的数据库实例,所以这种方法需要和第一、二种方法相配合才能使用。这种方法其实已经属于Oracle数据备份与恢复的范畴了,就是Oracle数据备份恢复方式中的物理备份恢复,所以这种方法可以叫做物理恢复法。 简单介绍物理恢复法,首先将一个已经存在数据库实例(最好已关闭)进行物理备份,所谓物理备份其实就是复制该数据库实例所使用的操作系统文件,这些文件主要包括DataFiles、RedoLogs、ControlFiles和UndoFiles(这些文件一般存在于$ORACLE_HOME/oradata目录下),进行数据库实例恢复的时候只需将备份的操作系统文件复制到新的oradata目录下即可,可以直接启动使用恢复后的该数据库实例。不难看出,这种备份恢复是依赖于操作系统平台的。 详细的物理备份和恢复介绍可以参考oracle的backup and recovery basics以及backup and recovery advanced user's guide。 说完了数据库实例的创建,现在来说说数据库实例的删除和修改。其实介绍完了数据库实例的创建,数据库实例的删除和修改就非常简单了。基本和前文数据库实例创建的内容相一致,且比较而言更简单。

Ping命令返回错误信息说明

以下内容未经全部验证,不保证正确性。 1.Request timed out 这是大家经常碰到的提示信息,很多文章中说这是对方机器置了过滤ICMP数据包,从上面工作过程来看,这是不完全正确的,至少有下几种情况。 (1) 对方已关机,或者网络上根本没有这个地址:比如在上图中主机A中PING 192.168.0.7 ,或者主机B关机了,在主机A中PING 192.168.0.5 都会得到超时的信息。 (2)对方与自己不在同一网段内,通过路由也无法找到对方,但有时对方确实是存在的,当然不存在也是返回超时的信息。 (3)对方确实存在,但设置了ICMP数据包过滤(比如防火墙设置)。 怎样知道对方是存在,还是不存在呢,可以用带参数 -a 的Ping命令探测对方,如果能得到对方的NETBIOS名称,则说明对方是存在的,是有防火墙设置,如果得不到,多半是对方不存在或关机,或不在同一网段内。 (4)错误设置IP地址 正常情况下,一台主机应该有一个网卡,一个IP地址,或多个网卡,多个IP地址(这些地址一定要处于不同的IP子网)。但如果一台电脑的“拨号网络适配器”(相当于一块软网卡)的TCP/IP设置中,设置了一个与网卡IP地址处于同一子网的IP地址,这样,在IP层协议看来,这台主机就有两个不同的接口处于同一网段内。当从这台主机Ping其他的机器时,会存在这样的问题: A.主机不知道将数据包发到哪个网络接口,因为有两个网络接口都连接在同一网段。 B.主机不知道用哪个地址作为数据包的源地址。因此,从这台主机去Ping其他机器,IP层协议会无法处理,超时后,Ping 就会给出一个“超时无应答”的错误信息提示。但从其他主机Ping这台主机时,请求包从特定的网卡来,ICMP只须简单地将目的、源地址互换,并更改一些标志即可,ICMP应答包能顺利发出,其他主机也就能成功Ping通这台机器了。 2.Destination host Unreachable (1) 对方与自己不在同一网段内,而自己又未设置默认的路由,比如上例中A机中不设定默认的路由,运行Ping192.168.0.1.4就会出现“Destination host Unreachable”。 (2)网线出了故障 这里要说明一下“destination host unreachable”和 “time out”的区别,如果所经过的路由器的路由表中具有到达目标的路由,而目标因为其他原因不可到达,这时候会出现“time out”,如果路由表中连到达目标的路由都没有,那就会出现“destination host unreachable”。 3.Bad IP address 这个信息表示您可能没有连接到DNS服务器,所以无法解析这个IP地址,也可能是IP地址不存在。 4.Source quench received 这个信息比较特殊,它出现的机率很少。它表示对方或中途的服务器繁忙无法回应。 5.Unknown host——不知名主机 这种出错信息的意思是,该远程主机的名字不能被域名服务器(DNS)转换成IP地址。故障原因可能是域名服务器有故障,或者其名字不正确,或者网络管理员的系统与远程主机之间的通信线路有故障。 6.No answer——无响应 这种故障说明本地系统有一条通向中心主机的路由,但却接收不到它发给该中心主机的任何信息。故障原因可能是下列之一:中心主机没有工作;本地或中心主机网络配置不正确;本地或中心的路由器没有工作;通信线路有故障;中心主机存在路由选择问题。 7.Ping 127.0.0.1 127.0.0.1是本地循环地址.如果本地址无法Ping通,则表明本地机TCP/IP协议不能正常工作。 8.no rout to host 网卡工作不正常。 9.transmit failed,error code:10043 网卡驱动不正常。 10.unknown host name DNS配置不正确

java客户端调用webservice

最近的工作是java和c++的交互,利用的就是webservice;博客中介绍了如何利用java生成webservice,这篇博客接着说如何利用java调用webservice。 我主要用的是axis2工具来实现java的webservice调用。 我比较常用的两种方法一个是直接利用RPCServiceClient的invokeBlocking方法,另外一种是OMAbstractFactory的createOMElement方法。其实这两种方式本质是一样的都是处理xml。因为webservice的基石就是xml。如果你用一个抓包工具来查看相关传输协议的传输信息的话,你会发现,其实这两种方式的执行过程都是通过互相传送xml数据来进行相关的webservice方法调用的。 主要过程就是java通过上面的方法把webservice的xml信息接收到,之后在把调用方法的参数信息填写到xml中,之后webservice服务端就通过你所填写的参数,执行相应的方法,返回相应的数据到xml中,之后java客户端进行解析之后获得相应的数据。这就是简单的一个执行流程。 知道执行流程之后,我们就要说说这两种方法的具体使用了。 首先导入jar是必须的,还是axis2的jar,不介绍怎么弄了,比较简单。 第一种方法: RPCServiceClient serviceClient = newRPCServiceClient(); Optionsoptions = serviceClient.getOptions(); EndpointReferencetargetEPR = new EndpointReference(url); options.setTo(targetEPR); // 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值 QName opAddEntry = new QName("http://service.wf.cypheta.com",method); 主要是建立RPCServiceClient客户对象,通过这个对象我们能够通过传入相应的webservice地址完成我们相应接口的调用。上面的url就是我们要传入的webservice的url。之后我们要建立QName对象,QName其实说白了就是有着特定格式的xml元素(命名空间+特定元素),我们通过传入命名空间和特定元素(这里是我们要调用的方法)之后定位到我们要执行方法的xml文件信息。 随后就是定义传入参数和返回值信息: Object[] opAddEntryArgs = new Object[]{481L}; // 返回参数类型,这个和axis1有点区别 // invokeBlocking方法有三个参数,其中第一个参数的类型是QName对象,表示要调用的方法名; // 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[]; // 第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。 // 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{} // 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法, // 该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同 Class[] classes = new Class[] {String.class }; /* Object[] object=serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes); for(int i=0;i<object.length;i++){ System.out.println(object[i]); }*/ System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0].toString()); 最后通过invokeBlocking方法获得一个对象数组,这里面它已经给我封装好了xml交互的操作,所以我们非常轻松的就能够调用webservice接口并且获得我们相应的数据。 第二种方法: 这种方法主要是自己动手来实现xml的交互:这里面包括四部分:1、设置发送请求的URL;2、设置调用的webservice地址;3、获得返回的xml数据;4、利用dom4j解析webservice返回的数据。 第一步: OMFactory fac = OMAbstractFactory.