Oct 25, 2008

【典藏】RAID技术

RAID是廉价磁盘冗余阵列的缩写,更现代的说法是,独立磁盘的冗余阵列。RAID这个概念最早是由1987年加州伯克利大学的David Patterson,Garth Gibson, Randy Katz提出的,他们的目标是展示一个RAID的性能可以达到或超过当时的一个单一的,大容量的,昂贵的磁盘。
在项目开发的过程中,随着频繁的磁盘失败,通过磁盘的冗余来避免磁盘数据的丢失已经是必须的了。这样一来,该项目的研究对于将来的RAID变得至关重要。
RAID的标准
许多RAID级别在技术上是可以实现的,但是不经常使用。以下完整的列出了RAID级别:
RAID 0:条带或串联
RAID 1:镜像
RAID 0+1:条带加镜像
RAID 1+0:镜像加条带
RAID 2:加重平衡编码修正(Hamming code correction)
RAID 3:使用专用奇偶校验的条带化
RAID 4:独立的读取和写入
RAID 5:带有分布式奇偶校验的条带化
串联---RAID 0 串联可以复合多个物理磁盘成为一个单独的虚拟磁盘,并按如下方式组织:地址空间是相邻的、没有数据冗余 、块(chunks)可以认为是物理磁盘或相邻区域的磁盘空间
串联----RAID 0
推动这种技术发展的主要原因是创建一个大于物理磁盘容量的虚拟磁盘设备。通过在逻辑上结合两个或更多物理磁盘来获得更大存储空间。串联也能使你扩展一个虚拟磁盘通过给它串联另外的物理磁盘。这项技术不限制磁盘大小,既成员磁盘的容量可以不同,而且不会损失磁盘空间。
阵列管理软件就是负责将3个物理磁盘复合成一个虚拟磁盘设备,对于应用来说,它只是个邻近的存储空间。
通过使用RAID 0的串联结构可以获得以下优点:
当数据遍布在多个磁盘上时,串联可以提高随机的I/O性能。
写性能也是相同的;如果是随机读取的话,也可以提高读性能。
磁盘的全部容量都可以为用户存储数据。
局限性主要包括:
只使用串联将没有冗余,串联的卷可以通过镜像达到冗余。
串联的可靠性较低,一个磁盘数据的丢失将导致所有磁盘数据的丢失
当磁盘满,数据会通过所有成员磁盘扩展,但是,当磁盘未满时,最后的磁盘将不被使用,降低了磁盘的利用率。

条带----RAID 0
条带可以复合多个物理磁盘成为一个单独的虚拟磁盘,并按如下方式组织:地址空间是分段的 、I/O流在磁盘与磁盘间交换、没有数据冗余 、对性能的增加有意义
条带----RAID 0
推动这种技术发展的主要原因是为了提高每秒I/O(IOPS)的性能。通过并行访问设备来增强性能。在并行访问中,虚拟设备中的所有磁盘大部分时间都用来服务I/O请求,所以提高了I/O的吞吐量。
阵列管理软件就是负责把整个阵列看做一个单独的虚拟磁盘。它使用多个物理磁盘并将它们复合为一个虚拟磁盘给应用。
I/O流被划分为称为条带(stripe)的段,从一个逻辑存储单元映射到两个或更多的物理磁盘。条带单元是隔行扫描的所以每个片上的复合空间也是交替的。
在这种结构下,没有数据保护,实际上,执行条带化后,丢失一个磁盘上的数据会导致所有条带磁盘的数据丢失。条带化增强了性能,但是降低了可靠性。
通过使用RAID 0条带化结构可以获得的优势是:
对于大量的连续的I/O请求和随机的I/O请求增强了性能。条带单元的大小可以根据顺序或随机存取而进行优化。
磁盘的全部容量都可以为用户存储数据。
局限性主要包括:
没有冗余
条带化的可靠性较低,丢失一个磁盘的数据将导致所有条带磁盘的数据丢失。
条带单元大小的策略:优化一个条带化RAID 0结构条带单元大小的策略依赖于卷访问的类型。
顺序访问环境
在一个顺序的环境里,当请求涉及到条带宽度范围内的所有磁盘成员时,条带化能够提高性能。举例来说,一个条带包含4个磁盘,一个I/O请求为128Kbytes,那么,配置条带单元的大小为32Kbytes。
随机访问环境
在一个随机环境里,条带化可以提高性能。随机访问受控于磁盘的搜索和寻道时间,随机的I/O要比顺序的I/O小很多,通常是从2Kbytes到8Kbytes。
当条带单元的大小配置为比请求的大小大很多的时候,性能得到优化。举例来说,对于一个8Kbytes的请求,至少配置条带单元的大小为16Kbytes。

镜像----RAID 1
镜像提供了数据的最大可用性,并有以下功能:所有数据的完全冗余拷贝、提高了读性能、透明化了磁盘失败
这项技术发展的主要原因是它能够提供高级别的可用性及可靠性。
镜像(RAID 1)通过数据在独立spindes上的多次记录来提供冗余。对于应用来讲,镜像磁盘显示为一个虚拟磁盘。一旦一个物理磁盘失败,失败磁盘上的镜像也就无效了,但系统继续通过未受影响的磁盘进行操作。
通过使用RAID 1的镜像结构可以获得如下的优点:
在一个或多个磁盘上可以获得一个完全冗余的数据拷贝
如果一个阵列中的镜像连接到不同的接口板,就可以达到非常高的数据可靠性级别。
所有驱动器都可以用来读取,提高了性能
在一个多用户或多任务环境下,当多个磁盘成员要获得满意的读效果时,镜像提高了读性能。相反,如果只有单一的卷读取进程,则将不能提高性能。
你可以设置3路镜像,但性能会受很大影响。在3路镜像中,写性能最大为44%。
局限性:
镜像需要使用两倍的磁盘,本质上占用了2倍的存储空间
镜像降低了大约15%的写性能,这实际上小于典型的RAID 5的写损失。(RAID 5的写性能最大到70%)。
镜像—条带(RAID 0+1)
镜像—条带(RAID 0+1) 复合条带化的镜像可以提供如下功能:极大的提高了性能、完全的数据冗余、透明化了磁盘失败。
使用复合条带和镜像的主要原因是获得RAID 0的性能和RAID 1的可用性。
安装它需要较高的花销,但许多用户认为它是值得投资的。
两个磁盘可以先进行条带化,然后进行镜像。可以获得镜像的高可靠性。因为同时使用了条带技术,它的性能要比单独使用镜像的性能要好得多。
它的一个优点就是有利于一个磁盘上分布数据的访问(提高了I/O per second),并增强了数据冗余。

局限性:RAID 0+1是高花销的镜像系统,需要2倍的独立磁盘空间。
条带----镜像(RAID 1+0)
条带----镜像(RAID 1+0) 复合镜像化的条带可以提供以下功能:极大的提高了性能 、完全的数据冗余、透明化了磁盘失败、比RAID 0+1提供了更高的磁盘失败容许
RAID 1+0拥有所有RAID 0+1性能及可靠性的优点,但它允许了更高级别的磁盘失败而不丢失数据。
RAID 1+0通常在磁盘失败后拥有更快的恢复时间,因为它只需要代替单独的条带来恢复而不是整个镜像。
RAID 1+0推荐在大型卷中使用,因为,失败的恢复时间是个关键。
RAID 1+0的概念根本不同于RAID 0+1,在RAID 1+0的配置中,每个条带是单独镜像的。
优点:
因为每个条带被独立镜像,可以容许大量的磁盘失败而无需禁止卷。
这个配置的性能优于RAID 0+1。
局限性:
RAID 1+0是高花销的镜像系统,需要2倍的独立磁盘空间。
带有分布式奇偶校验的条带化----RAID 5

一个RAID 5的卷结构可以进行镜像因为:
条带化结构拥有较好的读性能,可靠性得到提高,而且没有镜像花费高

附加功能包括:
对于单个的磁盘来说,单独访问是有效的。
数据和奇偶较验值都进行了条带化。
全部的随机的I/O性能依赖于写的百分率。如果写超过20%,那么就可以考虑选择RAID 0+1了。
优点
奇偶校验保护了单一磁盘的失败
RAID 5只需要一个附加的磁盘,其他的都可以用来存储数据。
局限性
在Veritas VM中,最少需要3块磁盘来完成RAID 5
RAID 5不可以被镜像,通过奇偶校验信息来提供冗余
写增强(Write-intersive)性能是很差劲的
如果写超过了20%,那么就可以考虑选择RAID 0+1了
在一个写增强的环境里,如果一个磁盘失败,将可能对性能产生严重的影响

性能因素
一个磁盘失败,数据仍然可以访问,但性能会受影响
从一个继续存在的磁盘读取数据 ----- 没有改变
从一个失败的磁盘读取数据 ----在条带中读取相对应的条带单元并于原始数据异或后(XOR)相连接
写一个继续存在的磁盘 ---- 如果失败的磁盘保存有奇偶校验的数据,写数据通常不计算奇偶校验。如果失败的磁盘保存有数据,那么将请求一个:读—修改—写的顺序
写入一个失败磁盘 ---- 继续存在的所有磁盘上的所有数据将与新数据使用异或(XOR)后进行连接,结果将写入到奇偶校验驱动器
从一个单一磁盘失败中恢复 ---- 在条带中余下的条带单元的数据被读取,使用异或(XOR)后进行连接,将结果写入替代的磁盘中,假定在配置中有一个有效的交换(spare)空间。
复合RAID模式
  
  单一的RAID模式肯定不能使用当前各种应用的需要,为了得到更多的性能,人们将各种RAID模式联合起来使用。那么将其中两种模式用在会有什么好处呢?可以得到功能更多、性能更好的RAID模式。一般符合RAID模式需要硬件控制器。因为对于如此复杂的应用软件RAID控制器显然是不现实的。RAID 0在各个单一模式中是速度最快的,所以在符合RAID模式中它也是最常用的。最长常用的符合RAID模式是0+1和1+0。 0+1和1+0是有细微区别的,不过有的公司对这个名词是不加以区分的——其实它们的主要区别在于容错能力。这两种复合RAID模式都至少需要4块硬盘。
  
  首先让我们看看RAID 0+1模式。复合使用RAID 0是为了提高磁盘性能,使用RAID 1为了提高容错性能。假设你有8块硬盘,将它们4个一组分成两个阵列——我将其称为基阵列,每个基阵列用RAID 0模式连接。然后你就有了两个延展模式的基阵列。然后你将这两个基阵列用RAID 1模式连接——也就是让其中一个基阵列作为另一个的镜像。如果一个延展模式的基阵列中的硬盘出现故障了,那么这个延展阵列也将全部瘫痪。不过另一个延展阵列仍然可以维持系统工作,并且可以利用其来恢复数据。
  
  RAID 1+0是先组合RAID 1阵列,然后把它们组成RAID 0模式。仍然使用刚才的例子:将8块硬盘分成4组,每组2块硬盘组成一个基阵列,然后将每个基阵列用RAID 1模式连接,也就是让其中一个硬盘作为另一个的镜像。然后把这4个RAID 1模式的基阵列用RAID 0模式连接。这个模式比RAID 0+1有更好的容错能力。任意的一个硬盘驱动器出现故障,因为有镜像驱动器的存在,所以整个阵列将能继续正常工作。
  
  从理论上讲RAID 1+0模式即使每个基阵列都坏一块硬盘,系统仍然能正常工作,只有当第五块出现故障的时候才有出现不可挽回的损失。而RAID 0+1只要两个基阵列都有一块硬盘故障,那么就无法挽回了。:~(
  
  目前流行的RAID 0+1和1+0模式使用了相对简单的复合技术就提高了性能和增强了数据冗余性。随着硬盘驱动器价格的不断下降,4块硬盘的价格也能为个人用户接受了。不过,如果你需要镜像功能的话,你所能使用的硬盘空间将只有两块硬盘空间大小——为了数据的稳定性,你不得不以牺牲50%的空间为代价。企业级应用以及服务器一般会不惜牺牲磁盘空间换取更高的容错性。另外还有一些其它的复合RAID模式比如:RAID 0+3、3+0、0+5、5+0、1+5、5+1。这些模式的实现往往需要昂贵的硬件支持。
  
RAID模式的选择
  
  现在你已经熟悉了不同的RAID组合模式及其配置,还有什么困扰你?对了,就是如果选择适合的RAID模式。一般用RAID无非就是为了这几个目的:数据冗余、容错性、提高容量、增进性能。数据冗余可以用于保护关键的数据不丢失,一般用于大型公司、企业,当然如果你有钱,也可以为了保护你的以GB为计数单位MP3使用它。容错能力可以带给存储系统更好的稳定。
  
  没RAID通过连接多个硬盘可以提供给计算机系统更大的存储空间。当然根据选择RAID模式的不同,你得到的最大存储空间是不同的,比如如果采用镜像技术,你所需要的空间是要存储数据的两倍。
  
  更多的,特别是个人用户使用RAID技术的目的是为了提高磁盘性能。当然你选择的RAID模式不同,性能的提高也会各不相同。
  
硬件RAID的实现
  
  首先看一下硬件实现RAID模式的方式:一般使用SCSI或者IDE/ATA作为硬盘同系统的接口。SCSI一般应用于高端服务器上,虽然性能优良、功能强大可是对于普通用户来讲价格太高。IDE/ATA RAID控制器成本低廉,(不少主板已经集成)虽然不能太复杂的应用,性能也比不上SCSI设备,但是对于家用市场来说已经能够满足要求了,所以渐渐成了RAID的主流。
  
  硬件RAID实现分为两种:一种是内置(或集成)RAID控制器,一种是外置RAID控制器。内置RAID控制器通常是常用的卡件的形式插接在计算机主板上,集成RAID控制器则是由主板厂商直接把控制芯片集成在主板上,近来高端主板集成RAID控制器几乎成了标准配置。根据RAID控制器以及连接模式不同,RAID控制器都配有不同数量的缓存,当然缓存越多,控制器的性能就越好了,价格也就越贵了。
  
  外部RAID控制器包括从控制器到硬盘等一套设备。在高端服务器上,你常常可以看到由独立的机箱容纳RAID控制器和硬盘。控制器包括了所有的RAID功能——在系统中看到的只是所有的逻辑驱动器。外部RAID控制器相比内置RAID控制器结构更加复杂,缓存容量更大。这是因为它常常要连接并且组织大量的硬盘来组成复杂的复合RAID来工作。它一般使用SCSI接口——可以进行热插拔,来更换有故障的硬盘,避免中置计算机系统停机所带来的损失。
  
  很明显内置控制器外置的便宜的多。不过外置控制器功能强大、可扩展性强,但是价格不是个人所能承受的。虽然IDE/ATA RAID控制器日渐增多,可是SCSI因其特殊的性能仍然是高端计算机系统的首选。当然你可以选择软件RAID——这是一个相当经济的选择,但是需要占用CPU时间,所以RAID模式越复杂,对于计算机系统影响就越大。所以如果你的预算足够还是选择硬件RAID模式吧

Oct 21, 2008

STL容器的基本特性和特征

1. STL有6种序列容器类型


(1)vector
它提供对元素的随即访问,在尾部添加和删除元素的时间是固定的,在头部或中部插入和删除元素的复杂度为线性时间。


(2)deque
文件中声明。
是双端队列,支持随即访问。从deque的开始与末尾位置插入和删除元素的时间是固定的。
尽管vector和deque都提供对元素的随机访问和在序列中部执行线性时间的插入和删除操作,但vector容器执行这些操作时速度更快一些。


(3)list
是双向链表,插入删除元素时间固定。不支持随机访问。
与vector不同是,当向容器中插入或删除元素后,链表迭代器指向元素将不变。
解释一下:如果一个vector有5个元素,中间插入一个,那么第五个元素包含的值将是以前第四个元素的值,因此,迭代器指向的位置不变,但是数据不同。然而,在链表中插入新元素并不会移动已有的元素,而只是修改链接信息。指向某个元素的迭代器仍然指向该元素,也就是值相同,链接的位置不同了。


(4)queue
头文件中声明。queue是一个适配器类,底层类默认为deque。
它不允许随机访问队列元素,甚至不允许遍历队列。
可以将元素添加到队尾,查看队尾和队首的元素的值,检查元素数目和测试队列是否为空。


(5)priority_queue
与queue的不同是,最大的元素总是在队首,也是一个适配器类,默认的底层类是vector。
可以修改用于确定哪个元素放在队首的比较方式,方法是提供一个可选的构造函数参数。


(6)stack
也是一个适配器类,默认的底层实现为vector。
不允许随机访问堆栈元素,甚至不允许遍历堆栈。
可以压入到栈顶,从栈顶弹出元素,查看栈顶元素的值,检查元素数目和测试堆栈是否为空。

2. STL有4种联合容器:set,multiset, map, multimap;


联合容器将值与关键字关联在一起,使用关键字来查找值。
关联容器的长处在于,它提供了对元素的快速访问。与序列相似,联合容器也允许插入新元素,不过不能指定元素的插入位置。原因是联合容器通常包含用于确定数据存放位置的算法,以便能够很快检索信息。

(1)set,multiset
前两种是在set头文件中(以前分别为set.h和multiset.h);
值的类型与关键字相同。set删除相同的元素,multiset不会。
(2)map,multimap
后两种是在map头文件中(以前分别为map.h和multimap.h)。
值的类型与关键字不同。map关键字唯一,multimap关键字不唯一。

STL中容器的比较

在stl中基本容器有string vector list deque set map


set 和map都是无序的保存元素 只能通过它提供的接口对里面的元素进行访问

set 集合, 用来判断某一个元素是不是在一个组里面 使用的比较少
map 映射 相当于字典 把一个值映射成另一个值 如果想创建字典的话使用它好了


string vector list deque set 是有序容器
string 是basic_string 的实现,
在内存中是连续存放的 为了提高效率,都会有保留内存,如string s= "abcd",这时s使用的空间可能就是255, 当string再次往s里面添加内容时不会再次分配内存 直到内容>255刊才会再次申请内存 因此提高了它的性能
当内容>255时 string会先分配一个新内存 然后再把内容复制过去 再复制先前的内容

对string的操作 如果是添加到最后时 一般不需要分配内存 所以性能最快
如果是对中间或是开始部分操作 如往那里添加元素或是删除元素 或是代替元素 这时需要进行内存复制 性能会降低

如果删除元素 string一般不会释放它已经分配的内存 为了是下次使用时可以更高效

由于string会有预保留内存 所以如果大量使用的话 会有内存浪费 这点需要考虑
还有就是删除元素时不释放过多的内存 这也要考虑

string中内存是在堆中分配的 所以串的长度可以很大 而char[] 是在栈中分配的 长度受到可使用的最大栈长度限制

如果对知道要使用的字符串的最大长度 那么可以使用普通的char[] 实现而不必使用string
string用在串长度不可知的情况 或是变化很大的情况

如果string已经经历了多次添加删除 现在的尺寸比最大的尺寸要小很多 想减少string使用的大小 可以使用
string s = "abcdefg";
string y(s); //因为再次分配内存时 y只会分配与s中内容大一点的内存 所以浪费不会很大
s.swap(y);//减少s使用的内存

如果内存够多的话就不用考虑这个了







capacity是查看现在使用内存的函数
大家可以试试看string分配一个一串后的capacity返回值
还有其它操作后的返回值

第二个是vector
vector就是动态数组 它也是在堆中分配内存 元素连续存放 有保留内存 如果减少大小后央存也不会释放 如果新值.当前大小时才会再分配内存
对最后元素操作最快 (在后面添加删除最快 ) 此时一般不需要移动内存 只有保留内存不够时才需要
对中间和开始处进行添加删除元素操作需要移动内存 如果你的元素是结构或是类 那么移动的同时还会进行构造和析构操作 所以性能不高

访问方面 对任何元素的访问都是O(1) 也就是是常数的 所以vector常用来保存需要经常进行随机访问的内容 并且不需要经常对中间元素进行添加删除操作

相比较可以看到vector的属性与string差不多 同样可以使用capacity看当前保留的内存
使用swap来减少它使用的内存

总结
需要经常随机访问请用vector






list
list就是链表 元素也是在堆中存放
每个元素都是放在一块内存中

list没有空间预留习惯 所以每分配一个元素都会从内存中分配
每删除一个元素都会释放它占用的内存 这与上面不同 可要看好了

list在哪里添加删除元素性能都很高 不需要移动内存 当然也不需要对每个元素都进行构造与析构了 所以常用来做随机操作容器
但是访问list里面的元素时就开始和最后访问最快
访问其它元素都是O(n) 所以 如果需要经常随机访问的话 还是使用其它的好

总结
如果你喜欢经常添加删除大对象的话 那么请使用list
要保存的对象不大 构造与析构操作不复杂 那么可以使用vector代替
list<指针> 完全是性能最低的做法 这种情况下还是使用vector<指针>好
因为指针没有构造与析构 也不占用很大内存







deque
双端队列

也是在堆中保存内容的

它的保存形式如下

[堆1]
...
[堆2]
...
[堆三]


每个堆保存好几个元素
然后堆和堆之间有指针指向

看起来像是list和vector的结合品
不过确实也是如此

deque的让你可以在前面快速的添加删除元素
或是在后面快速的添加删除元素
然后还可以比较高的随机访问速度

vector是可以快速的在最后添加删除元素 并可以快速的访问任意元素
list是可以快速的在所有地方添加删除元素 但是只能快速的访问最开始与最后的元素
deque在开始和最后添加元素都一样快 并提供了随机访问方法 像vector一样使用[]访问任意元素 但是 随机访问速度比不上vector快 因为它要内部处理堆跳转

deque也有保留空间 另外 由于deque不要求连续空间 所以可以保存的元素比vector更大 这点也要注意一下 还有就是在前面和后面添加元素时都不需要移动其它块的元素 所以 性能也很高

Oct 20, 2008

C++中为何提倡用const定义常量而不提倡#define

const定义常量是有数据类型的,而#define宏定义常量却没有。
这样const定义的常量编译器可以对其进行数据静态类型安全检查,而#define宏定义的常量却只是进行简单的字符替换,没有类型安全检查,且有时还会产生边际效应(不如你愿处)。所谓边际效应举例如下:
#define N 100
#define M 200 + N
当程序中使用 M*N 时,原本想要 100 * (200+ N )的却变成了 100 * 200 + N。
2。有些调试程序可对const进行调试,但不对#define进行调试。
3。当定义局部变量时,const作用域仅限于定义局部变量的函数体内。但用#define时其作用域不仅限于定义局部变量的函数体内,而是从定义点到整个程序的结束点。但也可以用#undef取消其定义从而限定其作用域范围。

彷徨

没有哪个时间会比这段日子更令人彷徨

猛的受挫了几次
于是开始直面自己的大学生活
我确实学了一点东西
但是是远远不够的
还是要继续学习,而时间已不够

值得庆幸的只有自己的态度和激情仍在
值得感伤的是时间已经不多了

还是不要放弃
就算是有限的生命,照样可以绽放无限的光彩
你是王,自己的王
一路前行的王
继续走自己喜欢的道路
赤足狂奔,暴走不停

Oct 13, 2008

vector的用法

线性结构中的顺序表有三种,向量,栈和队列
栈和队列在很多数据结构的书中都有论述到。唯独向量这一种顺序表很少
现在记录下vector的用法

/*
*-----------------------------------------
*先来C++,有关Vector类
*-----------------------------------------
*/
vector 抽象容器类型之一(还有list和deque等),与其他几中容器类型不同的是它高效支持随机访问其中的元素。
使用vector,首先必须调用头文件(#include )

它的声明和初始化是这样的
vector <类型名> 变量名
vector vi = ( 10 , 1 ) //初始化为10个元素的vector,每个元素都为1

push_back()的用法是将元素插入vector容器的最尾部
举个例子
vector vi;
int a[4] = { 0, 1, 2, 3};
for ( int i = 0; i<=4; ++i )
vi.push_back(a[i]);

此时vi就是0 1 2 3
如果改成
vi.push_front( a[i] );
vi就是 3 2 1 0


/*///////vector方法列表/////
1.toString()
2.reset(x,y)//重新赋值例如:myv.reset(2,3);
3.getclone()//复制.例如myv2=myv1.getclone();
4.eqV(v)//是否相等例如if(v1.eqv(v2)){};
5.addV(v),addVNew(v)和minusV(v),minusVNew(v)//加法减法v1.addV(v2);v3=v1.addVNew(v2);
6. scaleV(n)和scaleVNew(n)//伸长.见上
7.getLength()和setLength(n)//a=v1.getLength();v1.setLength(30);
8.getAngle()和setAngle(n)//得到与设置角度.
9.rot(n)和rotNew(n)//旋转
10.dot(v)//内积x=v1.dot(v2)
11.angleBetween(v)//得到夹角例如x=v1.angleBetween(v2);
*/


class vector {
var x:Number;
var y:Number;
// 用于返回属性值的方法
function toString():String {
return ("["+x+","+y+"]");
}
//改变属性值的方法.
function reset(getx:Number, gety:Number):Void {
x = getx;
y = gety;
}
//克隆向量.与mx不同//!!!!!!
function getclone():vector {
return new vector(x, y);
}
//比较相等否.
function eqV(getVector:vector):Boolean {
return (x == getVector.x && y == getVector.y);
}
//向量加法.
function addV(getVector:vector):Void {
x += getVector.x;
y += getVector.y;
}
//向量加法得到新向量.
function addVNew(getVector:vector):vector {
return new vector(x+getVector.x, y+getVector.y);
}
//向量减法
function minusV(getVector:vector):Void {
x -= getVector.x;
y -= getVector.y;
}
//向量减法得到新向量.
function minusVNew(getVector:vector):vector {
return new vector(x-getVector.x, y-getVector.y);
}
//向量缩放
function scaleV(n:Number):Void {
x *= n;
y *= n;
}
//向量缩放得到新向量.
function scaleVNew(n:Number):vector {
return new vector(x*n, y*n);
}
//得到向量的长度
function getLength():Number {
return Math.sqrt(x*x+y*y);
}
//设置向量长度
function setLength(len:Number):Void {
var r = this.getLength();
if (r) {
this.scaleV(len/r);
} else {
this.x = len;
}
}
//得到向量角度
function getAngle():Number {
return (180/Math.PI)*Math.atan2(y, x);
}
//设置向量角度
function setAngle(angle:Number):Void {
var r = this.getLength();
var tem = angle*(Math.PI/180);
x = r*Math.cos(tem);
y = r*Math.sin(tem);
}
//旋转.
function rot(angle:Number):Void {
var r = this.getLength();
var tem = angle*(Math.PI/180);
var ca = Math.cos(tem);
var sa = Math.sin(tem);
var rx = x*ca-y*sa;
var ry = x*sa+y*ca;
x = rx;
y = ry;
}
//旋转并得到新向量.
function rotNew(angle:Number):vector {
var v = new vector(x, y);
v.rotate(angle);
return v;
}
//内积
function dot(v:vector):Number {
return x*v.x+y*v.y;
}
//法向量计算省略.可以用rotateNew(90)得到.
//垂直验证省略.用(v1.dot(v2)==0)判断垂直.
//向量夹角.得到向量夹角绝对值.
function angleBetween(v:vector):Number {
var tem = this.dot(v);
return (180/Math.PI)*Math.acos(tem/(this.getLength()*v.getLength()));
}
// 构造函数
function vector(getx:Number, gety:Number) {
x = getx;
y = gety;
}
}

/*
*---------------------------------------
*另一个示范vector用法的c程序段
*来自C编程思想
*---------------------------------------
*/

#include < string.h >
#include < iostream.h >
#include < fstream.h >
#include < vector.h >
using namespace std;

int main() {
vector v;
ifstream in("Fillvector.cpp");
string line;
while(getline(in, line))
v.push_back(line); // Add the line to the end
// Add line numbers:
for(int i = 0; i < v.size(); i++)
cout << i << ": " << v[i] << endl;
} ///:~

getline获得文件的一行

int main() {
vector words;
ifstream in("GetWords.cpp");
string word;
while(in >> word)
words.push_back(word);
for(int i = 0; i < words.size(); i++)
cout << words[i] << endl;
} ///:~

while(in >> word)是以空格(space)为分割符来分割的

Oct 8, 2008

百度一面未果的师兄写的···

我投的是商务引擎研发工程师,后来才知道是百度的核心技术职位。笔试有3道题目,第一道是有N(N〉10000)个集合,每个集合有M个词,每个集合有集合号,现在有个待查找的词序列,返回词所在的集合号。我当时的想法是查找无非有两种好方法,一种是折半,一种是HASH。词没有联系,只能用HASH了。第二道把两个有序的序列,排列成整体有序的序列,我用的是两个折半。
今天的面试感觉发挥不是很好,先自我介绍了一下,主要是项目和获奖情况。然后让我写蜜网项目的architecture,感觉讲得不是很到位。面试官对我做得项目也不是很感兴趣。然后开始C++基础问答,诸如拷贝构造函数作用,缺省拷贝构造函数危害,虚函数作用,指针和引用。缺省拷贝构造函数危害没有答上来,其他的都还勉强。然后是一道证明题,快速排序的时间复杂度,并证明。这个就基本不会了。第一道程序题很简单,写出字符串逆序输出的代码。我很快就写完了,然后面试官就叫我在自己的程序里找错误,费了九牛二虎之力终于把错误找完了,纸上写程序真的不习惯。第二道题,vector类,包括构造函数,插入,查找。。。我就答不上来了,STL只用过LIST。还有一道题,在log文件,包括时间 网址 关键字,统计每个关键字的出现次数。我的想法是用二叉树,面试官点了一下头,应该思路是对的,然后面试官接着问如果这个log文件数据是海量,内存装不下,怎么办。我就不知道怎么回答了。还有一道智力题,大概计算一下下面那条马路的车流量,说出你的思路。我的想法是高峰时段观察5-10分钟,低谷时段考察5-10分钟,平常时段考察5-10分钟,然后加权平均


【swetter想说的话】
当时笔试百度的时候做的是和这位师兄一样的题,只是那时候的数据结构很弱,因此连个一面的机会都没有。后来为了准备微软的笔试,恶补了几天数据结构,C++后的STL也是猛看,现在再看一面的题,C++基础基本没问题,缺省拷贝构造函数的危害就在于它是浅拷贝,不小心就会造成RUNTIME ERROR。第一道程序题将字符串逆序输出,其实就可以使用STL中的vector容器,这是可置换的,使用一个迭代器,和rbegin(),rend()函数就可以轻松搞定。vector类的构造函数,插入,查找。。。只要会用向量类,这个不难。。log文件那个就不行了,哎,数据结构还需要继续加强。。。不然找不到工作啊,加油加油

时间复杂度的计算

一个是时间复杂度,一个是渐近时间复杂度。前者是某个算法的时间耗费,它是该算法所求解问题规模n的函数,而后者是指当问题规模趋向无穷大时,该算法时间复杂度的数量级。 当我们评价一个算法的时间性能时,主要标准就是算法的渐近时间复杂度,因此,在算法分析时,往往对两者不予区分,经常是将渐近时间复杂度T(n)=O(f(n))简称为时间复杂度,其中的f(n)一般是算法中频度最大的语句频度。 此外,算法中语句的频度不仅与问题规模有关,还与输入实例中各元素的取值相关。但是我们总是考虑在最坏的情况下的时间复杂度。以保证算法的运行时间不会比它更长。 常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n^2)、立方阶O(n^3)、k次方阶O(n^k)、指数阶O(2^n)。 下面我们通过例子加以说明,让大家碰到问题时知道如何去解决。
1、设三个函数f,g,h分别为 f(n)=100n^3+n^2+1000 , g(n)=25n^3+5000n^2 , h(n)=n^1.5+5000nlgn 请判断下列关系是否成立: (1) f(n)=O(g(n)) (2) g(n)=O(f(n)) (3) h(n)=O(n^1.5) (4) h(n)=O(nlgn) 这里我们复习一下渐近时间复杂度的表示法T(n)=O(f(n)),这里的"O"是数学符号,它的严格定义是"若T(n)和f(n)是定义在正整数集合上的两个函数,则T(n)=O(f(n))表示存在正的常数C和n0 ,使得当n≥n0时都满足0≤T(n)≤C?f(n)。"用容易理解的话说就是这两个函数当整型自变量n趋向于无穷大时,两者的比值是一个不等于0的常数。这么一来,就好计算了吧。
◆ (1)成立。题中由于两个函数的最高次项都是n^3,因此当n→∞时,两个函数的比值是一个常数,所以这个关系式是成立的。
◆ (2)成立。与上同理。
◆ (3)成立。与上同理。
◆ (4)不成立。由于当n→∞时n^1.5比nlgn递增的快,所以h(n)与nlgn的比值不是常数,故不成立。 2、设n为正整数,利用大"O"记号,将下列程序段的执行时间表示为n的函数。
(1) i=1; k=0 while(i (2) x=n; // n>1 while (x>=(y+1)*(y+1)) y++; 解答:T(n)=n1/2 ,T(n)=O(n1/2), 最坏的情况是y=0,那么循环的次数是n1/2次,这是一个按平方根阶递增的函数。 (3) x=91; y=100; while(y>0) if(x>100) {x=x-10;y--;} else x++; 解答: T(n)=O(1), 这个程序看起来有点吓人,总共循环运行了1000次,但是我们看到n没有? 没。这段程序的运行是和n无关的,就算它再循环一万年,我们也不管他,只是一个常数阶的函数。

Oct 6, 2008

七年前的CSDN


哇卡卡卡卡,google出来的图片



缓存地址
http://web.archive.org/web/20010917024432/www.csdn.net/

Oct 3, 2008

【典藏】NP问题

 NP完全问题是不确定性图灵机在P时间内能解决的问题,是世界七大数学难题之一。
  NP完全问题排在百万美元大奖的首位,足见他的显赫地位和无穷魅力。
  数学上著名的NP问题,完整的叫法是NP完全问题,也即“NP COMPLETE”问题,简单的写法,是 NP=P?的问题。问题就在这个问号上,到底是NP等於P,还是NP不等於P。证明其中之一,便可以拿百万美元大奖。
  这个奖还没有人拿到,也就是说,NP问题到底是Polynomial(意思是多项式的),还是Non-Polynomial,尚无定论。
  NP里面的N,不是Non-Polynomial的N,是Non-Deterministic(意思是非确定性的),P代表Polynomial倒是对的。NP就是Non-deterministic Polynomial的问题,也即是多项式复杂程度的非确定性问题。
  什么是非确定性问题呢?有些计算问题是确定性的,比如加减乘除之类,你只要按照公式推导,按部就班一步步来,就可以得到结果。但是,有些问题是无法按部就班直接地计算出来。比如,找大质数的问题。有没有一个公式,你一套公式,就可以一步步推算出来,下一个质数应该是多少呢?这样的公式是没有的。再比如,大的合数分解质因数的问题,有没有一个公式,把合数代进去,就直接可以算出,它的因子各自是多少?也没有这样的公式。
  这种问题的答案,是无法直接计算得到的,只能通过间接的“猜算”来得到结果。这也就是非确定性问题。而这些问题的通常有个算法,它不能直接告诉你答案是什么,但可以告诉你,某个可能的结果是正确的答案还是错误的。这个可以告诉你“猜算”的答案正确与否的算法,假如可以在多项式时间内算出来,就叫做多项式非确定性问题。而如果这个问题的所有可能答案,都是可以在多项式时间内进行正确与否的验算的话,就叫完全多项式非确定问题。
  完全多项式非确定性问题可以用穷举法得到答案,一个个检验下去,最终便能得到结果。但是这样算法的复杂程度,是指数关系,因此计算的时间随问题的复杂程度成指数的增长,很快便变得不可计算了。
  人们发现,所有的完全多项式非确定性问题,都可以转换为一类叫做满足性问题的逻辑运算问题。既然这类问题的所有可能答案,都可以在多项式时间内计算,人们於是就猜想,是否这类问题,存在一个确定性算法,可以在指数时间内,直接算出或是搜寻出正确的答案呢?这就是著名的NP=P?的猜想。
  解决这个猜想,无非两种可能,一种是找到一个这样的算法,只要针对某个特定NP完全问题找到一个算法,所有这类问题都可以迎刃而解了,因为他们可以转化为同一个问题。另外的一种可能,就是这样的算法是不存在的。那么就要从数学理论上证明它为什么不存在。
  前段时间轰动世界的一个数学成果,是几个印度人提出了一个新算法,可以在多项式时间内,证明某个数是或者不是质数,而在这之前,人们认为质数的证明,是个非多项式问题。可见,有些看来好象是非多项式的问题,其实是多项式问题,只是人们一时还不知道它的多项式解而已。
  如果判定问题π∈NP,并且对所有其他判定问题 π∈NP,都有π'多项式变换到π(记为π'∞π),则称判定问题π 是NP完全的。
  对P类,NP类及NP完全问题的研究推动 了计算复杂性理论的发展,产生了许多新概念,提出了许多新方法。但是还有许多难题至今没有解决,P=NP?就是其中之一。许多学者猜想P≠NP,但无法证明。

Oct 2, 2008

【典藏】Win32 API 绘图相关函数

API之文本和字体函数

AddFontResource 在Windows系统中添加一种字体资源
CreateFont 用指定的属性创建一种逻辑字体
CreateFontIndirect 用指定的属性创建一种逻辑字体
CreateScalableFontResource 为一种TureType字体创建一个资源文件,以便能用

API函数AddFontResource将其加入Windows系统
DrawText 将文本描绘到指定的矩形中
DrawTextEx 与DrawText相似,只是加入了更多的功能
EnumFontFamilies 列举指定设备可用的字体
EnumFontFamiliesEx 列举指定设备可用的字体
EnumFonts 列举指定设备可用的字体
ExtTextOut 经过扩展的文本描绘函数。也请参考SetTextAlign函数
GetAspectRatioFilterEx 用SetMapperFlags要求Windows只选择与设备当前纵横

比相符的光栅字体时,本函数可判断纵横比大小
GetCharABCWidths 判断TureType字体中一个或多个字符的A-B-C大小
GetCharABCWidthsFloat 查询一种字体中一个或多个字符的A-B-C尺寸
GetCharacterPlacement 该函数用于了解如何用一个给定的字符显示一个字串
GetCharWidth 调查字体中一个或多个字符的宽度
GetFontData 接收一种可缩放字体文件的数据
GetFontLanguageInfo 返回目前选入指定设备场景中的字体的信息
GetGlyphOutline 取得TureType字体中构成一个字符的曲线信息
GetKerningPairs 取得指定字体的字距信息
GetOutlineTextMetrics 接收与TureType字体内部特征有关的详细信息
GetRasterizerCaps 了解系统是否有能力支持可缩放的字体
GetTabbedTextExtent 判断一个字串占据的范围,同时考虑制表站扩充的因素
GetTextAlign 接收一个设备场景当前的文本对齐标志
GetTextCharacterExtra 判断额外字符间距的当前值
GetTextCharset 接收当前选入指定设备场景的字体的字符集标识符
GetTextCharsetInfo 获取与当前选定字体的字符集有关的详细信息
GetTextColor 判断当前字体颜色。通常也称为“前景色”
GetTextExtentExPoint 判断要填入指定区域的字符数量。也用一个数组装载每个

字符的范围信息
GetTextExtentPoint 判断一个字串的大小(范围)
GetTextFace 获取一种字体的字样名
GetTextMetrics 获取与选入一种设备场景的物理字体有关的信息
GrayString 描绘一个以灰色显示的字串。通常由Windows用于标识禁止状态
PolyTextOut 描绘一系列字串
RemoveFontResource 从Windows系统中删除一种字体资源
SetMapperFlags Windows对字体进行映射时,可用该函数选择与目标设备的纵横

比相符的光栅字体
SetTextAlign 设置文本对齐方式,并指定在文本输出过程中使用设备场景的当前

位置
SetTextCharacterExtra 描绘文本的时候,指定要在字符间插入的额外间距
SetTextColor 设置当前文本颜色。这种颜色也称为“前景色”
SetTextJustification 通过指定一个文本行应占据的额外空间,可用这个函数对

文本进行两端对齐处理
TabbedTextOut 支持制表站的一个文本描绘函数
TextOut 文本绘图函数

API之菜单函数

AppendMenu 在指定的菜单里添加一个菜单项
CheckMenuItem 复选或撤消复选指定的菜单条目
CheckMenuRadioItem 指定一个菜单条目被复选成“单选”项目
CreateMenu 创建新菜单
CreatePopupMenu 创建一个空的弹出式菜单
DeleteMenu 删除指定的菜单条目
DestroyMenu 删除指定的菜单
DrawMenuBar 为指定的窗口重画菜单
EnableMenuItem 允许或禁止指定的菜单条目
GetMenu 取得窗口中一个菜单的句柄
GetMenuCheckMarkDimensions 返回一个菜单复选符的大小
GetMenuContextHelpId 取得一个菜单的帮助场景ID
GetMenuDefaultItem 判断菜单中的哪个条目是默认条目
GetMenuItemCount 返回菜单中条目(菜单项)的数量
GetMenuItemID 返回位于菜单中指定位置处的条目的菜单ID
GetMenuItemInfo 取得(接收)与一个菜单条目有关的特定信息
GetMenuItemRect 在一个矩形中装载指定菜单条目的屏幕坐标信息
GetMenuState 取得与指定菜单条目状态有关的信息
GetMenuString 取得指定菜单条目的字串
GetSubMenu 取得一个弹出式菜单的句柄,它位于菜单中指定的位置
GetSystemMenu 取得指定窗口的系统菜单的句柄
HiliteMenuItem 控制顶级菜单条目的加亮显示状态
InsertMenu 在菜单的指定位置处插入一个菜单条目,并根据需要将其他条目向下

移动
InsertMenuItem 插入一个新菜单条目
IsMenu 判断指定的句柄是否为一个菜单的句柄
LoadMenu 从指定的模块或应用程序实例中载入一个菜单
LoadMenuIndirect 载入一个菜单
MenuItemFromPoint 判断哪个菜单条目包含了屏幕上一个指定的点
ModifyMenu 改变菜单条目
RemoveMenu 删除指定的菜单条目
SetMenu 设置窗口菜单
SetMenuContextHelpId 设置一个菜单的帮助场景ID
SetMenuDefaultItem 将一个菜单条目设为默认条目
SetMenuItemBitmaps 设置一幅特定位图,令其在指定的菜单条目中使用,代替标

准的复选符号(√)
SetMenuItemInfo 为一个菜单条目设置指定的信息
TrackPopupMenu 在屏幕的任意地方显示一个弹出式菜单
TrackPopupMenuEx 与TrackPopupMenu相似,只是它提供了额外的功能

API之位图、图标和光栅运算函数
BitBlt 将一幅位图从一个设备场景复制到另一个
CopyIcon 制作指定图标或鼠标指针的一个副本。这个副本从属于发出调用的应用

程序
CopyImage 复制位图、图标或指针,同时在复制过程中进行一些转换工作
CreateBitmap 按照规定的格式创建一幅与设备有关位图
CreateBitmapIndirect 创建一幅与设备有关位图
CreateCompatibleBitmap 创建一幅与设备有关位图,它与指定的设备场景兼容
CreateCursor 创建一个鼠标指针
CreateDIBitmap 根据一幅与设备无关的位图创建一幅与设备有关的位图
CreateDIBSection 创建一个DIBSection
CreateIcon 创建一个图标
CreateIconIndirect 创建一个图标
DestroyCursor 清除指定的鼠标指针,并释放它占用的所有系统资源
DestroyIcon 清除图标
DrawIcon 在指定的位置画一个图标
DrawIconEx 描绘一个图标或鼠标指针。与DrawIcon相比,这个函数提供了更多的

功能
ExtractAssociatedIcon 判断一个可执行程序或DLL中是否存在图标,或是否有图

标与系统注册表中指定的文件存在关联并提取之
ExtractIcon 判断一个可执行文件或DLL中是否有图标存在,并将其提取出来
GetBitmapBits 将来自位图的二进制位复制到一个缓冲区
GetBitmapDimensionEx 取得一幅位图的宽度和高度
GetDIBColorTable 从选入设备场景的DIBSection中取得颜色表信息
GetDIBits 将来自一幅位图的二进制位复制到一幅与设备无关的位图里
GetIconInfo 取得与图标有关的信息
GetStretchBltMode 判断StretchBlt 和 StretchDIBits函数采用的伸缩模式
LoadBitmap 从指定的模块或应用程序实例中载入一幅位图
LoadCursor 从指定的模块或应用程序实例中载入一个鼠标指针
LoadCursorFromFile 在一个指针文件或一个动画指针文件的基础上创建一个指针


LoadIcon 从指定的模块或应用程序实例中载入一个图标
LoadImage 载入一个位图、图标或指针
MaskBlt 执行复杂的图象传输,同时进行掩模(MASK)处理
PatBlt 在当前选定的刷子的基础上,用一个图案填充指定的设备场景
PlgBlt 复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋

转处理
SetBitmapBits 将来自缓冲区的二进制位复制到一幅位图
SetBitmapDimensionEx 设置一幅位图的宽度。以一毫米的十分之一为单位
SetDIBColorTable 设置选入设备场景的一个DIBSection的颜色表信息
SetDIBits 将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里
SetDIBitsToDevice 将一幅与设备无关位图的全部或部分数据直接复制到一个设


SetStretchBltMode 指定StretchBlt 和 StretchDIBits函数的伸缩模式
StretchBlt 将一幅位图从一个设备场景复制到另一个
StretchDIBits 将一幅与设备无关位图的全部或部分数据直接复制到指定的设备

场景

API之绘图函数

AbortPath 抛弃选入指定设备场景中的所有路径。也取消目前正在进行的任何路

径的创建工作
AngleArc 用一个连接弧画一条线
Arc 画一个圆弧
BeginPath 启动一个路径分支
CancelDC 取消另一个线程里的长时间绘图操作
Chord 画一个弦
CloseEnhMetaFile 关闭指定的增强型图元文件设备场景,并将新建的图元文件返

回一个句柄
CloseFigure 描绘到一个路径时,关闭当前打开的图形
CloseMetaFile 关闭指定的图元文件设备场景,并向新建的图元文件返回一个句


CopyEnhMetaFile 制作指定增强型图元文件的一个副本(拷贝)
C
opyMetaFile 制作指定(标准)图元文件的一个副本
CreateBrushIndirect 在一个LOGBRUSH数据结构的基础上创建一个刷子
CreateDIBPatternBrush 用一幅与设备无关的位图创建一个刷子,以便指定刷子

样式(图案)
CreateEnhMetaFile 创建一个增强型的图元文件设备场景
CreateHatchBrush 创建带有阴影图案的一个刷子
CreateMetaFile 创建一个图元文件设备场景
CreatePatternBrush 用指定了刷子图案的一幅位图创建一个刷子
CreatePen 用指定的样式、宽度和颜色创建一个画笔
CreatePenIndirect 根据指定的LOGPEN结构创建一个画笔
CreateSolidBrush 用纯色创建一个刷子
DeleteEnhMetaFile 删除指定的增强型图元文件
DeleteMetaFile 删除指定的图元文件
DeleteObject 删除GDI对象,对象使用的所有系统资源都会被释放
DrawEdge 用指定的样式描绘一个矩形的边框
DrawEscape 换码(Escape)函数将数据直接发至显示设备驱动程序
DrawFocusRect 画一个焦点矩形
DrawFrameControl 描绘一个标准控件
DrawState 为一幅图象或绘图操作应用各式各样的效果
Ellipse 描绘一个椭圆,由指定的矩形围绕
EndPath 停止定义一个路径
EnumEnhMetaFile 针对一个增强型图元文件,列举其中单独的图元文件记录
EnumMetaFile 为一个标准的windows图元文件枚举单独的图元文件记录
EnumObjects 枚举可随同指定设备场景使用的画笔和刷子
ExtCreatePen 创建一个扩展画笔(装饰或几何)
ExtFloodFill 在指定的设备场景里,用当前选择的刷子填充一个区域
FillPath 关闭路径中任何打开的图形,并用当前刷子填充
FillRect 用指定的刷子填充一个矩形
FlattenPath 将一个路径中的所有曲线都转换成线段
FloodFill 用当前选定的刷子在指定的设备场景中填充一个区域
FrameRect 用指定的刷子围绕一个矩形画一个边框
GdiComment 为指定的增强型图元文件设备场景添加一条注释信息
GdiFlush 执行任何未决的绘图操作
GdiGetBatchLimit 判断有多少个GDI绘图命令位于队列中
GdiSetBatchLimit 指定有多少个GDI绘图命令能够进入队列
GetArcDirection 画圆弧的时候,判断当前采用的绘图方向
GetBkColor 取得指定设备场景当前的背景颜色
GetBkMode 针对指定的设备场景,取得当前的背景填充模式
GetBrushOrgEx 判断指定设备场景中当前选定刷子起点
GetCurrentObject 获得指定类型的当前选定对象
GetCurrentPositionEx 在指定的设备场景中取得当前的画笔位置
GetEnhMetaFile 取得磁盘文件中包含的一个增强型图元文件的图元文件句柄
GetEnhMetaFileBits 将指定的增强型图元文件复制到一个内存缓冲区里
GetEnhMetaFileDescription 返回对一个增强型图元文件的说明
GetEnhMetaFileHeader 取得增强型图元文件的图元文件头
GetEnhMetaFilePaletteEntries 取得增强型图元文件的全部或部分调色板
GetMetaFile 取得包含在一个磁盘文件中的图元文件的图元文件句柄
GetMetaFileBitsEx 将指定的图元文件复制到一个内存缓冲区
GetMiterLimit 取得设备场景的斜率限制(Miter)设置
GetNearestColor 根据设备的显示能力,取得与指定颜色最接近的一种纯色
GetObjectAPI 取得对指定对象进行说明的一个结构
GetObjectType 判断由指定句柄引用的GDI对象的类型
GetPath 取得对当前路径进行定义的一系列数据
GetPixel 在指定的设备场景中取得一个像素的RGB值
GetPolyFillMode 针对指定的设备场景,获得多边形填充模式
GetROP2 针对指定的设备场景,取得当前的绘图模式
GetStockObject 取得一个固有对象(Stock)
GetSysColorBrush 为任何一种标准系统颜色取得一个刷子
GetWinMetaFileBits 通过在一个缓冲区中填充用于标准图元文件的数据,将一个

增强型图元文件转换成标准windows图元文件
InvertRect 通过反转每个像素的值,从而反转一个设备场景中指定的矩形
LineDDA 枚举指定线段中的所有点
LineTo 用当前画笔画一条线,从当前位置连到一个指定的点
MoveToEx 为指定的设备场景指定一个新的当前画笔位置
PaintDesk 在指定的设备场景中描绘桌面墙纸图案
PathToRegion 将当前选定的路径转换到一个区域里
Pie 画一个饼图
PlayEnhMetaFile 在指定的设备场景中画一个增强型图元文件
PlayEnhMetaFileRecord 回放单独一条增强型图元文件记录
PlayMetaFile 在指定的设备场景中回放一个图元文件
PlayMetaFileRecord 回放来自图元文件的单条记录
PolyBezier 描绘一条或多条贝塞尔(Bezier)曲线
PolyDraw 描绘一条复杂的曲线,由线段及贝塞尔曲线组成
Polygon 描绘一个多边形
Polyline 用当前画笔描绘一系列线段
PolyPolygon 用当前选定画笔描绘两个或多个多边形
PolyPolyline 用当前选定画笔描绘两个或多个多边形
Rectangle 用当前选定的画笔描绘矩形,并用当前选定的刷子填充
RoundRect 用当前选定的画笔画一个圆角矩形,并用当前选定的刷子在其中填充


SelectClipPath 将设备场景当前的路径合并到剪切区域里
SelectObject 为当前设备场景选择图形对象
SetArcDirection 设置圆弧的描绘方向
SetBkColor 为指定的设备场景设置背景颜色
SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式
SetBrushOrgEx 为指定的设备场景设置当前选定刷子的起点
SetEnhMetaFileBits 用指定内存缓冲区内包含的数据创建一个增强型图元文件
SetMetaFileBitsEx 用包含在指定内存缓冲区内的数据结构创建一个图元文件
SetMiterLimit 设置设备场景当前的斜率限制
SetPixel 在指定的设备场景中设置一个像素的RGB值
SetPixelV 在指定的设备场景中设置一个像素的RGB值
SetPolyFillMode 设置多边形的填充模式
SetROP2 设置指定设备场景的绘图模式。与vb的DrawMode属性完全一致
SetWinMetaFileBits 将一个标准Windows图元文件转换成增强型图元文件
StrokeAndFillPath 针对指定的设备场景,关闭路径上打开的所有区域
StrokePath 用当前画笔描绘一个路径的轮廓。打开的图形不会被这个函数关闭
UnrealizeObject 将一个刷子对象选入设备场景之前,如刷子的起点准备用

SetBrushOrgEx修改,则必须先调用本函数
WidenPath 根据选定画笔的宽度,重新定义当前选定的路径

API之设备场景函数

CombineRgn 将两个区域组合为一个新区域
CombineTransform 驱动世界转换。它相当于依顺序进行两次转换
CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景
CreateDC 为专门设备创建设备场景
CreateEllipticRgn 创建一个椭圆
CreateEllipticRgnIndirect 创建一个内切于特定矩形的椭圆区域
CreateIC 为专用设备创建一个信息场景
CreatePolygonRgn 创建一个由一系列点围成的区域
CreatePolyPolygonRgn 创建由多个多边形构成的区域。每个多边形都应是封闭的


CreateRectRgn 创建一个矩形区域
CreateRectRgnIndirect 创建一个矩形区域
CreateRoundRectRgn 创建一个圆角矩形
DeleteDC 删除专用设备场景或信息场景,释放所有相关窗口资源
DPtoLP 将点阵从设备坐标转换到专用设备场景逻辑坐标
EqualRgn 确定两个区域是否相等
ExcludeClipRect 从专用设备场景的剪裁区中去掉一个矩形区。矩形内不能进行

绘图
ExcludeUpdateRgn 从专用设备场景剪裁区去掉指定窗口的刷新区域
ExtCreateRegion 根据世界转换修改区域
ExtSelectClipRgn 将指定区域组合到设备场景的当前剪裁区
FillRgn 用指定刷子填充指定区域
FrameRgn 用指定刷子围绕指定区域画一个外框
GetBoundsRect 获取指定设备场景的边界矩形
GetClipBox 获取完全包含指定设备场景剪裁区的最小矩形
GetClipRgn 获取设备场景当前剪裁区
GetDC 获取指定窗口的设备场景
GetDCEx 为指定窗口获取设备场景。相比GetDC,本函数提供了更多的选项
GetDCOrgEx 获取指定设备场景起点位置(以屏幕坐标表示)
GetDeviceCaps 根据指定设备场景代表的设备的功能返回信息
GetGraphicsMode 确定是否允许增强图形模式(世界转换)
GetMapMode 为特定设备场景调入映象模式
GetRegionData 装入描述一个区域信息的RgnData结构或缓冲区
GetRgnBox 获取完全包含指定区域的最小矩形
GetUpdateRgn 确定指定窗口的刷新区域。该区域当前无效,需要刷新
GetViewportExtEx 获取设备场景视口(viewport)范围
GetViewportOrgEx 获取设备场景视口起点
GetWindowDC 获取整个窗口(包括边框、滚动条、标题栏、菜单等)的设备场景


GetWindowExtEx 获取指定设备场景的窗口范围
GetWindowOrgEx 获取指定设备场景的逻辑窗口的起点
GetWindowRgn 获取窗口区域
GetWorldTransform 如果有世界转换,为设备场景获取当前世界转换
IntersectClipRect 为指定设备定义一个新的剪裁区
InvalidateRgn 使窗口指定区域不活动,并将它加入窗口刷新区,使之可随后被

重画
InvertRgn 通过颠倒每个像素值反转设备场景指定区域
LPtoDP 将点阵从指定设备场景逻辑坐标转换为设备坐标
ModifyWorldTransform 根据指定的模式修改世界转换
OffsetClipRgn 按指定量平移设备场景剪裁区
OffsetRgn 按指定偏移量平移指定区域
OffsetViewportOrgEx 平移设备场景视口区域
OffsetWindowOrgEx 平移指定设备场景窗口起点
PaintRgn 用当前刷子背景色填充指定区域
PtInRegion 确定点是否在指定区域内
PtVisible 确定指定点是否可见(即,点是否在设备场景剪裁区内)
RectInRegion 确定矩形是否有部分在指定区域内
RectVisible 确定指定矩形是否有部分可见(是否在设备场景剪裁区内)
ReleaseDC 释放由调用GetDC或GetWindowDC函数获取的指定设备场景
RestoreDC 从设备场景堆栈恢复一个原先保存的设备场景
SaveDC 将指定设备场景状态保存到Windows设备场景堆栈
ScaleViewportExtEx 缩放设备场景视口的范围
ScaleWindowExtEx 缩放指定设备场景窗口范围
ScrollDC 在窗口(由设备场景代表)中水平和(或)垂直滚动矩形
SelectClipRgn 为指定设备场景选择新的剪裁区
SetBoundsRect 设置指定设备场景的边界矩形
SetGraphicsMode 允许或禁止增强图形模式,以提供某些支持(包括世界转换)


SetMapMode 设置指定设备场景的映射模式
SetRectRgn 设置区域为指定的矩形
SetViewportExtEx 设置设备场景视口范围
SetViewportOrgEx 设置设备场景视口起点
SetWindowExtEx 设置指定设备场景窗口范围
SetWindowOrgEx 设置指定设备场景窗口起点
SetWindowRgn 设置窗口区域
SetWorldTransform 设置世界转换
ValidateRgn 激活窗口中指定区域,把它从刷新区移走
WindowFromDC 取回与某一设备场景相关的窗口的句柄

Oct 1, 2008

【转】哈佛大学凌晨四点的景象


馆训:
1.现在睡觉的话会做梦而现在学习的话会让梦实现
This moment will nap, you will have a dream; But this moment study,you will interpret a dream.
2.我无所事事地度过的今天是昨天死去的人们所奢望的明天
I leave uncultivated today, was precisely yesterday
perishes tomorrow which person of the body implored.
3.感到晚了的时候其实是最快的时候
Thought is already is late, exactly is the earliest time.
4.不要把今天的事拖到明天
Not matter of the today will drag tomorrow.
5.学习的痛苦是一时的而没有学习的痛苦是一辈子的
Time the study pain is temporary, has not learned the pain islife-long.
6.学习不是人生的全部但连学习都征服不了你还能做什么?
The study certainly is not the life complete. But, sincecontinually life part of - studies also is unable to conquer, what butalso can make?
7.学习不是因为缺少时间而是缺少努力
Studies this matter, lacks the time, but is lacks diligently.
8.所有人的成功都不是偶然的
Nobody can casually succeed, it comes from the thoroughself-control and the will.郭澧葱
9.无法避免的痛苦就去享受吧!
Please enjoy the pain which is unable to avoid.
10.早起的鸟儿有虫吃
Only has compared to the others early, diligently diligently, canfeel the successful taste.
11.成功并不属于每个人
Nobody can casually succeed
12.时间在流逝
HOW time flies
13.今天流下的口水将变成明天流下的泪水
Now drips the saliva, will become tomorrow the tear
谨以此文,警醒所有把大学当幼儿园过的同学。
Powered By Blogger