给文件和文件夹增加右键菜单:复制路径

2012年5月19日 没有评论

转载请指明出处:http://blog.acmol.com/copy-path
(这是我的一篇老文,在我老博客上发过,今天重装系统了,用到了这个,就转过来了)

先写一个程序,实现的功能是将该程序从命令行获得的参数复制到剪切板。

C++代码如下(建工程时选用win32项目,不要选win32控制台应用项目):
(使用gcc编译的话请加上-mwindows选项,以防止产生一闪而过的控制台)

 

#include<Windows.h>

#include<string.h>

BOOL CopyToClipboard(const WCHAR* pszData, const int nDataLen)

{

 

if(::OpenClipboard(NULL))

{

::EmptyClipboard();

HGLOBAL clipbuffer;

WCHAR *buffer;

clipbuffer = ::GlobalAlloc(GMEM_DDESHARE, (nDataLen+1)*2);

buffer = (WCHAR *)::GlobalLock(clipbuffer);

wcscpy(buffer, pszData);

::GlobalUnlock(clipbuffer);

::SetClipboardData(CF_UNICODETEXT, clipbuffer);

::CloseClipboard();

return TRUE;

}

return FALSE;

}

WCHAR* AToW(char* String)

{

if (String == NULL)

{

return NULL;

}

size_t aLen = strlen( String ) + 1;

int wLen = MultiByteToWideChar(CP_UTF8,0,String,aLen,NULL,0);

WCHAR* lpw = new WCHAR [wLen];

MultiByteToWideChar(CP_ACP,0,String,aLen,lpw,wLen);

return lpw;

}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)

{

WCHAR* newstr=AToW(lpCmdLine);

CopyToClipboard(newstr,wcslen(newstr));

delete newstr;

}

如果没有相关编译器,可以点此直接下载该可执行文件

生成可执行文件之后,把可执行文件命名为getpath.exe(或者其它什么也行,下面以此为例)

然后把 getpath.exe放到 系统盘的 “Windows/system32/” 目录下。

然后,打开注册表编辑器(开始菜单->运行->regedit),找到【HKEY_CLASSES_ROOTAllFilesystemObjectsshell】项,在里面新建一个项,名字可以任意起,将其默认值修改为”复制路径(&Z)”,其中(&Z)表示快捷键设置为Z。然后再在刚才新建的项里新建一个项,叫command,把其默认值设置成getpath %1 即可。

现在你可以试着对着一个文件或文件夹点右键,就能看到右键菜单里多了一项:复制路径,点击之后就会自动将其文件的完整路径复制到剪切板里。‍

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 行业技术 标签:

标准输入,标准输出是行缓冲?

2012年5月17日 没有评论

当且仅当标准输入和标准输出并不涉及交互作用设备时,它们才是全缓存的。
标准出错是不带缓存的。
如若是涉及终端设备的其他流,则它们是行缓存的;否则是全缓存的。
对任何一个给定的流,如果我们并不喜欢这些系统默认,则可调用下列两个函数中的一个更改缓存类型:
void setbuf(FILE *fp, char *buf);
int setvbuf(FILE *fp, char *buf, int mode, size_t size);可以看《UNIX高级编程》第五章介绍
================================================================================================
读上面这句话没读到什么感觉有意义的东西的人,看看下面程序:

主要是我写了个测试程序

//fortest.cc
#include <cstdio>
int main(){                                                                                                                           

    while(1){
        sleep(1);
        printf("1111111111111111111111111111111111111\n");
        //fflush(stdout);
    }
}

然后,直接执行,得到的结果是每秒输出一行输出
然后我又用一个程序想利用管道获取其标准输出,谁知道竟然一直阻塞着读不到数据。。。后来把fflush(stdout)加上,就能读到了~不解原因, 后来就查到了上面那段话,豁然开朗。。

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 行业技术 标签:

[转载]Zookeeper与paxos算法

2012年5月14日 没有评论

 

一、            zookeeper是什么

官方说辞:Zookeeper 分布式服务框架是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

好抽象,我们改变一下方式,先看看它都提供了哪些功能,然后再看看使用它的这些功能能做点什么。

 

二、            zookeeper提供了什么

简单的说,zookeeper=文件系统+通知机制。

1、 文件系统

Zookeeper维护一个类似文件系统的数据结构:

图 1 Zookeeper 数据结构

 

每个子目录项如 NameService 都被称作为 znode,和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。

有四种类型的znode:

1、PERSISTENT-持久化目录节点

客户端与zookeeper断开连接后,该节点依旧存在

2、 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

3、EPHEMERAL-临时目录节点

客户端与zookeeper断开连接后,该节点被删除

4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

 

2、 通知机制

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。

 

就这么简单,下面我们看看能做点什么呢?

 

三、            我们能用zookeeper做什么

1、 命名服务

这个似乎最简单,在zookeeper的文件系统里创建一个目录,即有唯一的path。在我们使用tborg无法确定上游程序的部署机器时即可与下游程序约定好path,通过path即能互相探索发现,不见不散了。

 

2、 配置管理

程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。好吧,现在把这些配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。

 

图 2. 配置管理结构图

3、 集群管理

所谓集群管理无在乎两点:是否有机器退出和加入、选举master。

对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。

对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

 

图 3. 集群管理结构图

4、  分布式锁

有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。

对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。厕所有言:来也冲冲,去也冲冲,用完删除掉自己创建的distribute_lock 节点就释放出锁。

对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。

 

5、队列管理

两种类型的队列:

1、 同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。

2、队列按照 FIFO 方式进行入队和出队操作。

第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

 

终于了解完我们能用zookeeper做什么了,可是作为一个程序员,我们总是想狂热了解zookeeper是如何做到这一点的,单点维护一个文件系统没有什么难度,可是如果是一个集群维护一个文件系统保持数据的一致性就非常困难了。

 

四、            分布式与数据复制

Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处:

1、 容错
一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;

2、提高系统的扩展能力
把负载分布到多个节点上,或者增加节点来提高系统的负载能力;

3、提高性能
让客户端本地访问就近的节点,提高用户访问速度。

 

从客户端读写访问的透明度来看,数据复制集群系统分下面两种:

1、写主(WriteMaster)
对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离;

2、写任意(Write Any)
对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。

 

对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。

我们关注的重点还是在如何保证数据在集群所有机器的一致性,这就涉及到paxos算法。

 

五、            数据一致性与paxos算法

据说Paxos算法的难理解与算法的知名度一样令人敬仰,所以我们先看如何保持数据的一致性,这里有个原则就是:

在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。

Paxos算法解决的什么问题呢,解决的就是保证每个节点执行相同的操作序列。好吧,这还不简单,master维护一个全局写队列,所有写操作都必须放入这个队列编号,那么无论我们写多少个节点,只要写操作是按编号来的,就能保证一致性。没错,就是这样,可是如果master挂了呢。

Paxos算法通过投票来对写操作进行全局编号,同一时刻,只有一个写操作被批准,同时并发的写操作要去争取选票,只有获得过半数选票的写操作才会被批准(所以永远只会有一个写操作得到批准),其他的写操作竞争失败只好再发起一轮投票,就这样,在日复一日年复一年的投票中,所有写操作都被严格编号排序。编号严格递增,当一个节点接受了一个编号为100的写操作,之后又接受到编号为99的写操作(因为网络延迟等很多不可预见原因),它马上能意识到自己数据不一致了,自动停止对外服务并重启同步过程。任何一个节点挂掉都不会影响整个集群的数据一致性(总2n+1台,除非挂掉大于n台)。

总结一下,数据一致性是如何保证的?是投票投出来的,幸福也是一样啊。

参考资料,直接复制有图片和部分文字:

http://blog.csdn.net/chen77716/article/details/6166675

http://blog.sina.com.cn/s/blog_5374d6e30100sn4l.html

http://rdc.taobao.com/team/jm/archives/448

http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

[转载]Zookeeper工作原理

2012年5月14日 没有评论

 

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。Zookeeper是hadoop的一个子项目,其发展历程无需赘述。在分布式应用中,由于工程师不能很好地使用锁机制,以及基于消息的协调机制不适合在某些应用中使用,因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此。本文简单分析zookeeper的工作原理,对于如何使用zookeeper不是本文讨论的重点。

 

1 Zookeeper的基本概念

1.1 角色

Zookeeper中的角色主要有以下三类,如下表所示:

系统模型如图所示:

1.2 设计目的

1.最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。

2 .可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。

3 .实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。

4 .等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。

5.原子性:更新只能成功或者失败,没有中间状态。

6 .顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

2 ZooKeeper的工作原理

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

每个Server在工作过程中有三种状态:

  • LOOKING:当前Server不知道leader是谁,正在搜寻
  • LEADING:当前Server即为选举出来的leader
  • FOLLOWING:leader已经选举出来,当前Server与之同步

2.1 选主流程

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程:

  1. 1 .选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2. 2 .选举线程首先向所有Server发起一次询问(包括自己);
  3. 3 .选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4. 4.  收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5. 5.  线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.

每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。选主的具体流程图如下所示:

fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。其流程图如下所示:

2.2 同步流程

选完leader以后,zk就进入状态同步过程。

  1. 1. leader等待server连接;
  2. 2 .Follower连接leader,将最大的zxid发送给leader;
  3. 3 .Leader根据follower的zxid确定同步点;
  4. 4 .完成同步后通知follower 已经成为uptodate状态;
  5. 5 .Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

流程图如下所示:

2.3 工作流程

2.3.1 Leader工作流程

Leader主要有三个功能:

  1. 1 .恢复数据;
  2. 2 .维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
  3. 3 .Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。

PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
Leader的工作流程简图如下所示,在实际实现中,流程要比下图复杂得多,启动了三个线程来实现功能。

2.3.2 Follower工作流程

Follower主要有四个功能:

  1. 1. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
  2. 2 .接收Leader消息并进行处理;
  3. 3 .接收Client的请求,如果为写请求,发送给Leader进行投票;
  4. 4 .返回Client结果。

Follower的消息循环处理如下几种来自Leader的消息:

  1. 1 .PING消息: 心跳消息;
  2. 2 .PROPOSAL消息:Leader发起的提案,要求Follower投票;
  3. 3 .COMMIT消息:服务器端最新一次提案的信息;
  4. 4 .UPTODATE消息:表明同步完成;
  5. 5 .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
  6. 6 .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。

Follower的工作流程简图如下所示,在实际实现中,Follower是通过5个线程来实现功能的。

对于observer的流程不再叙述,observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。

转载自:http://stblog.baidu-tech.com/?p=1164

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

[转载]MYSQL event 按时间触发的任务

2012年5月14日 没有评论

MYSQL5.1之后开始支持event,能够按时间触发一个sql语句。
具体用法如下:
查看是否开启event:
show variables like ‘%event%’
如果没开启,使用下列的任意一句开启计划任务:

SET GLOBAL event_scheduler = ON;
SET @@global.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;   — 0代表关闭
SET @@global.event_scheduler = 1;

创建event语法:

CREATE EVENT [ IF NOT EXISTS ] event_name
ON SCHEDULE AT|EVERY
[ ON COMPLETION [ NOT ] PRESERVE ]
[ ENABLED | DISABLED ]        –状态,默认是有效状态。
[ COMMENT 'comment' ]         –注释说明
DO sql_statement;

主要功能说明:
AT 表示指定一个时间只执行一次。
EVERY 周期性计划,可指定计划开始时间 STARTS 和结束时间 ENDS,执行具体时间周期可以为:YEAR, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND。
COMPLETION 计划任务完毕后,该计划任务对象是否还在数据库中保留。默认不保留。

实例0:
每5分钟删除sms表上面ybmid为空白且createdate距现时间超过5分钟的数据。


USE test;
CREATE EVENT event_delnull
ON SCHEDULE
EVERY 5 MINUTE STARTS ’2010-07-10 00:00:00′ ENDS ’2011-02-10 00:00:00′
DO
DELETE FROM sms WHERE ybmid=” AND TIMEDIFF(SYSDATE(),createdate)>’00:05:00′;

实例1:
每天调用存储过程一次:


mysql> delimiter //
mysql> create event updatePTOonSunday
    -> on schedule every 1 day
-> do
-> call updatePTO();
-> //
Query OK, 0 rows affected (0.02 sec)

这里updatePTO()是我数据库里自定义的存储过程

查看任务计划:

SELECT * FROM mysql.eventG
 

更改计划任务
语法:

ALTER EVENT
[DEFINER = { user | CURRENT_USER }] #更改缺省用户
event_name
[ON SCHEDULE schedule]          #更改调度时间
[RENAME TO new_event_name]          #计划任务改名
[ON COMPLETION [NOT] PRESERVE]      #更改一次运行结束后的行为
[ENABLE | DISABLE | SLAVESIDE_DISABLED] #更改计划任务状态
[COMMENT 'comment']               #修改注释
[DO sql_statement]                     #修改计划执行体

三、删除计划任务
语法:

 DROP EVENT [IF EXISTS] event_name

四、开启MySQL计划任务功能支持
MySQL中对计划任务的支持是采用线程调度检测计划任务的。要此功能开启计划任务才会执行。查看调度器状态命令如下:

 SHOW [FULL] PROCESSLISTG

如下是没有开启的状态:

mysql> SHOW FULL PROCESSLISTG
*************************** 1. row ***************************
Id: 10
User: root
Host: localhost:4823
db: mysql
Command: Query
Time: 0
State: NULL
Info: SHOW FULL PROCESSLIST
1 row in set (0.00 sec)

通过如下全局配置的设置来开启或关闭调度器:

 SET GLOBAL event_scheduler = ON/OFF/1/0; –开/关

 SET @@global.event_scheduler = ON/OFF/1/0;

五、示例如下:
其中计划任务体内可以是简单语句,也可以调用存储过程

 delimiter //
drop event if exists createmonsterevent//
create event createmonsterevent
on schedule every 20 minute
starts CURRENT_TIMESTAMP + INTERVAL 10 minute
ENABLE
COMMENT ‘刷怪计划任务’
DO
begin
#20分钟
Call createmonster(date_sub(sysdate(),INTERVAL 24 minute),
date_sub(sysdate(),INTERVAL 2 minute));
end;
//
delimiter ;

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

【转载】理解mysql-MYSQL索引与优化

2012年5月11日 没有评论

写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点。考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录。如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多)。如果对之建立B-Tree索引,则只需要进行log100(10^6)=3次页面读取,最坏情况下耗时30ms。这就是索引带来的效果,很多时候,当你的应用程序进行SQL查询速度很慢时,应该想想是否可以建索引。进入正题:

第二章、索引与优化

1、选择索引的数据类型

MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。通常来说,可以遵循以下一些指导原则:

(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。
(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。
(3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。

1.1、选择标识符
选择合适的标识符是非常重要的。选择时不仅应该考虑存储类型,而且应该考虑MySQL是怎样进行运算和比较的。一旦选定数据类型,应该保证所有相关的表都使用相同的数据类型。
(1)    整型:通常是作为标识符的最好选择,因为可以更快的处理,而且可以设置为AUTO_INCREMENT。

(2)    字符串:尽量避免使用字符串作为标识符,它们消耗更好的空间,处理起来也较慢。而且,通常来说,字符串都是随机的,所以它们在索引中的位置也是随机的,这会导致页面分裂、随机访问磁盘,聚簇索引分裂(对于使用聚簇索引的存储引擎)。

2、索引入门
对于任何DBMS,索引都是进行优化的最主要的因素。对于少量的数据,没有合适的索引影响不是很大,但是,当随着数据量的增加,性能会急剧下降。
如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能对索引最左边的前缀进行有效的查找。例如:
假设存在组合索引it1c1c2(c1,c2),查询语句select * from t1 where c1=1 and c2=2能够使用该索引。查询语句select * from t1 where c1=1也能够使用该索引。但是,查询语句select * from t1 where c2=2不能够使用该索引,因为没有组合索引的引导列,即,要想使用c2列进行查找,必需出现c1等于某值。

2.1、索引的类型
索引是在存储引擎中实现的,而不是在服务器层中实现的。所以,每种存储引擎的索引都不一定完全相同,并不是所有的存储引擎都支持所有的索引类型。
2.1.1、B-Tree索引
假设有如下一个表:

CREATE TABLE People (

last_name varchar(50)    not null,

first_name varchar(50)    not null,

dob        date           not null,

gender     enum(‘m’, ‘f’) not null,

key(last_name, first_name, dob)

);

其索引包含表中每一行的last_name、first_name和dob列。其结构大致如下:

索引存储的值按索引列中的顺序排列。可以利用B-Tree索引进行全关键字、关键字范围和关键字前缀查询,当然,如果想使用索引,你必须保证按索引的最左边前缀(leftmost prefix of the index)来进行查询。
(1)匹配全值(Match the full value):对索引中的所有列都指定具体的值。例如,上图中索引可以帮助你查找出生于1960-01-01的Cuba Allen。
(2)匹配最左前缀(Match a leftmost prefix):你可以利用索引查找last name为Allen的人,仅仅使用索引中的第1列。
(3)匹配列前缀(Match a column prefix):例如,你可以利用索引查找last name以J开始的人,这仅仅使用索引中的第1列。
(4)匹配值的范围查询(Match a range of values):可以利用索引查找last name在Allen和Barrymore之间的人,仅仅使用索引中第1列。
(5)匹配部分精确而其它部分进行范围匹配(Match one part exactly and match a range on another part):可以利用索引查找last name为Allen,而first name以字母K开始的人。
(6)仅对索引进行查询(Index-only queries):如果查询的列都位于索引中,则不需要读取元组的值。
由于B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY。当然,使用B-tree索引有以下一些限制:
(1) 查询必须从索引的最左边的列开始。关于这点已经提了很多遍了。例如你不能利用索引查找在某一天出生的人。
(2) 不能跳过某一索引列。例如,你不能利用索引查找last name为Smith且出生于某一天的人。
(3) 存储引擎不能使用索引中范围条件右边的列。例如,如果你的查询语句为WHERE last_name=”Smith” AND first_name LIKE ‘J%’ AND dob=’1976-12-23′,则该查询只会使用索引中的前两列,因为LIKE是范围查询。

2.1.2、Hash索引
MySQL中,只有Memory存储引擎显示支持hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B-Tree索引。Memory存储引擎支持非唯一hash索引,这在数据库领域是罕见的,如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。
假设创建如下一个表:
CREATE TABLE testhash (
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
KEY USING HASH(fname)
) ENGINE=MEMORY;
包含的数据如下:

假设索引使用hash函数f( ),如下:

f(‘Arjen’) = 2323

f(‘Baron’) = 7437

f(‘Peter’) = 8784

f(‘Vadim’) = 2458

此时,索引的结构大概如下:

Slots是有序的,但是记录不是有序的。当你执行
mysql> SELECT lname FROM testhash WHERE fname=’Peter’;
MySQL会计算’Peter’的hash值,然后通过它来查询索引的行指针。因为f(‘Peter’) = 8784,MySQL会在索引中查找8784,得到指向记录3的指针。
因为索引自己仅仅存储很短的值,所以,索引非常紧凑。Hash值不取决于列的数据类型,一个TINYINT列的索引与一个长字符串列的索引一样大。

Hash索引有以下一些限制:
(1)由于索引仅包含hash code和记录指针,所以,MySQL不能通过使用索引避免读取记录。但是访问内存中的记录是非常迅速的,不会对性造成太大的影响。
(2)不能使用hash索引排序。
(3)Hash索引不支持键的部分匹配,因为是通过整个索引值来计算hash值的。
(4)Hash索引只支持等值比较,例如使用=,IN( )和<=>。对于WHERE price>100并不能加速查询。
2.1.3、空间(R-Tree)索引
MyISAM支持空间索引,主要用于地理空间数据类型,例如GEOMETRY。
2.1.4、全文(Full-text)索引
全文索引是MyISAM的一个特殊索引类型,主要用于全文检索。

3、高性能的索引策略
3.1、聚簇索引(Clustered Indexes)
聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不宜建立聚簇索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引。因为由存储引擎实现索引,所以,并不是所有的引擎都支持聚簇索引。目前,只有solidDB和InnoDB支持。
聚簇索引的结构大致如下:

注:叶子页面包含完整的元组,而内节点页面仅包含索引的列(索引的列为整型)。一些DBMS允许用户指定聚簇索引,但是MySQL的存储引擎到目前为止都不支持。InnoDB对主键建立聚簇索引。如果你不指定主键,InnoDB会用一个具有唯一且非空值的索引来代替。如果不存在这样的索引,InnoDB会定义一个隐藏的主键,然后对其建立聚簇索引。一般来说,DBMS都会以聚簇索引的形式来存储实际的数据,它是其它二级索引的基础。

3.1.1、InnoDB和MyISAM的数据布局的比较
为了更加理解聚簇索引和非聚簇索引,或者primary索引和second索引(MyISAM不支持聚簇索引),来比较一下InnoDB和MyISAM的数据布局,对于如下表:

 

CREATE TABLE layout_test (

col1 int NOT NULL,

col2 int NOT NULL,

PRIMARY KEY(col1),

KEY(col2)

);

假设主键的值位于1—10,000之间,且按随机顺序插入,然后用OPTIMIZE TABLE进行优化。col2随机赋予1—100之间的值,所以会存在许多重复的值。
(1)    MyISAM的数据布局
其布局十分简单,MyISAM按照插入的顺序在磁盘上存储数据,如下:

注:左边为行号(row number),从0开始。因为元组的大小固定,所以MyISAM可以很容易的从表的开始位置找到某一字节的位置。
据些建立的primary key的索引结构大致如下:

注:MyISAM不支持聚簇索引,索引中每一个叶子节点仅仅包含行号(row number),且叶子节点按照col1的顺序存储。
来看看col2的索引结构:

实际上,在MyISAM中,primary key和其它索引没有什么区别。Primary key仅仅只是一个叫做PRIMARY的唯一,非空的索引而已。

(2)    InnoDB的数据布局
InnoDB按聚簇索引的形式存储数据,所以它的数据布局有着很大的不同。它存储表的结构大致如下:

注:聚簇索引中的每个叶子节点包含primary key的值,事务ID和回滚指针(rollback pointer)——用于事务和MVCC,和余下的列(如col2)。

相对于MyISAM,二级索引与聚簇索引有很大的不同。InnoDB的二级索引的叶子包含primary key的值,而不是行指针(row pointers),这减小了移动数据或者数据页面分裂时维护二级索引的开销,因为InnoDB不需要更新索引的行指针。其结构大致如下:

聚簇索引和非聚簇索引表的对比:

 

3.1.2、按primary key的顺序插入行(InnoDB)

如果你用InnoDB,而且不需要特殊的聚簇索引,一个好的做法就是使用代理主键(surrogate key)——独立于你的应用中的数据。最简单的做法就是使用一个AUTO_INCREMENT的列,这会保证记录按照顺序插入,而且能提高使用primary key进行连接的查询的性能。应该尽量避免随机的聚簇主键,例如,字符串主键就是一个不好的选择,它使得插入操作变得随机。

 

3.2、覆盖索引(Covering Indexes)
如果索引包含满足查询的所有数据,就称为覆盖索引。覆盖索引是一种非常强大的工具,能大大提高查询性能。只需要读取索引而不用读取数据有以下一些优点:
(1)索引项通常比记录要小,所以MySQL访问更少的数据;
(2)索引都按值的大小顺序存储,相对于随机访问记录,需要更少的I/O;
(3)大多数据引擎能更好的缓存索引。比如MyISAM只缓存索引。
(4)覆盖索引对于InnoDB表尤其有用,因为InnoDB使用聚集索引组织数据,如果二级索引中包含查询所需的数据,就不再需要在聚集索引中查找了。
覆盖索引不能是任何索引,只有B-TREE索引存储相应的值。而且不同的存储引擎实现覆盖索引的方式都不同,并不是所有存储引擎都支持覆盖索引(Memory和Falcon就不支持)。
对于索引覆盖查询(index-covered query),使用EXPLAIN时,可以在Extra一列中看到“Using index”。例如,在sakila的inventory表中,有一个组合索引(store_id,film_id),对于只需要访问这两列的查询,MySQL就可以使用索引,如下:

mysql> EXPLAIN SELECT store_id, film_id FROM sakila.inventoryG

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: inventory

type: index

possible_keys: NULL

key: idx_store_id_film_id

key_len: 3

ref: NULL

rows: 5007

Extra: Using index

1 row in set (0.17 sec)

在大多数引擎中,只有当查询语句所访问的列是索引的一部分时,索引才会覆盖。但是,InnoDB不限于此,InnoDB的二级索引在叶子节点中存储了primary key的值。因此,sakila.actor表使用InnoDB,而且对于是last_name上有索引,所以,索引能覆盖那些访问actor_id的查询,如:

 

mysql> EXPLAIN SELECT actor_id, last_name

-> FROM sakila.actor WHERE last_name = ‘HOPPER’G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: actor

type: ref

possible_keys: idx_actor_last_name

key: idx_actor_last_name

key_len: 137

ref: const

rows: 2

Extra: Using where; Using index

 

3.3、利用索引进行排序
MySQL中,有两种方式生成有序结果集:一是使用filesort,二是按索引顺序扫描。利用索引进行排序操作是非常快的,而且可以利用同一索引同时进行查找和排序操作。当索引的顺序与ORDER BY中的列顺序相同且所有的列是同一方向(全部升序或者全部降序)时,可以使用索引来排序。如果查询是连接多个表,仅当ORDER BY中的所有列都是第一个表的列时才会使用索引。其它情况都会使用filesort。

create table actor(

actor_id int unsigned NOT NULL AUTO_INCREMENT,

name      varchar(16) NOT NULL DEFAULT ”,

password        varchar(16) NOT NULL DEFAULT ”,

PRIMARY KEY(actor_id),

KEY     (name)

) ENGINE=InnoDB

insert into actor(name,password) values(‘cat01′,’1234567′);

insert into actor(name,password) values(‘cat02′,’1234567′);

insert into actor(name,password) values(‘ddddd’,’1234567′);

insert into actor(name,password) values(‘aaaaa’,’1234567′);

 

 

mysql> explain select actor_id from actor order by actor_id G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: actor

type: index

possible_keys: NULL

key: PRIMARY

key_len: 4

ref: NULL

rows: 4

Extra: Using index

1 row in set (0.00 sec)

 

mysql> explain select actor_id from actor order by password G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: actor

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 4

Extra: Using filesort

1 row in set (0.00 sec)

 

mysql> explain select actor_id from actor order by name G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: actor

type: index

possible_keys: NULL

key: name

key_len: 18

ref: NULL

rows: 4

Extra: Using index

1 row in set (0.00 sec)

当MySQL不能使用索引进行排序时,就会利用自己的排序算法(快速排序算法)在内存(sort buffer)中对数据进行排序,如果内存装载不下,它会将磁盘上的数据进行分块,再对各个数据块进行排序,然后将各个块合并成有序的结果集(实际上就是外排序)。对于filesort,MySQL有两种排序算法。
(1)两遍扫描算法(Two passes)
实现方式是先将须要排序的字段和可以直接定位到相关行数据的指针信息取出,然后在设定的内存(通过参数sort_buffer_size设定)中进行排序,完成排序之后再次通过行指针信息取出所需的Columns。
注:该算法是4.1之前采用的算法,它需要两次访问数据,尤其是第二次读取操作会导致大量的随机I/O操作。另一方面,内存开销较小。
(3)    一次扫描算法(single pass)
该算法一次性将所需的Columns全部取出,在内存中排序后直接将结果输出。
注:从 MySQL 4.1 版本开始使用该算法。它减少了I/O的次数,效率较高,但是内存开销也较大。如果我们将并不需要的Columns也取出来,就会极大地浪费排序过程所需要的内存。在 MySQL 4.1 之后的版本中,可以通过设置 max_length_for_sort_data 参数来控制 MySQL 选择第一种排序算法还是第二种。当取出的所有大字段总大小大于 max_length_for_sort_data 的设置时,MySQL 就会选择使用第一种排序算法,反之,则会选择第二种。为了尽可能地提高排序性能,我们自然更希望使用第二种排序算法,所以在 Query 中仅仅取出需要的 Columns 是非常有必要的。

当对连接操作进行排序时,如果ORDER BY仅仅引用第一个表的列,MySQL对该表进行filesort操作,然后进行连接处理,此时,EXPLAIN输出“Using filesort”;否则,MySQL必须将查询的结果集生成一个临时表,在连接完成之后进行filesort操作,此时,EXPLAIN输出“Using temporary;Using filesort”。

 

3.4、索引与加锁
索引对于InnoDB非常重要,因为它可以让查询锁更少的元组。这点十分重要,因为MySQL 5.0中,InnoDB直到事务提交时才会解锁。有两个方面的原因:首先,即使InnoDB行级锁的开销非常高效,内存开销也较小,但不管怎么样,还是存在开销。其次,对不需要的元组的加锁,会增加锁的开销,降低并发性。
InnoDB仅对需要访问的元组加锁,而索引能够减少InnoDB访问的元组数。但是,只有在存储引擎层过滤掉那些不需要的数据才能达到这种目的。一旦索引不允许InnoDB那样做(即达不到过滤的目的),MySQL服务器只能对InnoDB返回的数据进行WHERE操作,此时,已经无法避免对那些元组加锁了:InnoDB已经锁住那些元组,服务器无法解锁了。
来看个例子:

create table actor(

actor_id int unsigned NOT NULL AUTO_INCREMENT,

name      varchar(16) NOT NULL DEFAULT ”,

password        varchar(16) NOT NULL DEFAULT ”,

PRIMARY KEY(actor_id),

KEY     (name)

) ENGINE=InnoDB

insert into actor(name,password) values(‘cat01′,’1234567′);

insert into actor(name,password) values(‘cat02′,’1234567′);

insert into actor(name,password) values(‘ddddd’,’1234567′);

insert into actor(name,password) values(‘aaaaa’,’1234567′);

SET AUTOCOMMIT=0;

BEGIN;

SELECT actor_id FROM actor WHERE actor_id < 4

AND actor_id <> 1 FOR UPDATE;

该查询仅仅返回2—3的数据,实际已经对1—3的数据加上排它锁了。InnoDB锁住元组1是因为MySQL的查询计划仅使用索引进行范围查询(而没有进行过滤操作,WHERE中第二个条件已经无法使用索引了):

 

mysql> EXPLAIN SELECT actor_id FROM test.actor

-> WHERE actor_id < 4 AND actor_id <> 1 FOR UPDATE G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: actor

type: index

possible_keys: PRIMARY

key: PRIMARY

key_len: 4

ref: NULL

rows: 4

Extra: Using where; Using index

1 row in set (0.00 sec)

 

mysql>

表明存储引擎从索引的起始处开始,获取所有的行,直到actor_id<4为假,服务器无法告诉InnoDB去掉元组1。
为了证明row 1已经被锁住,我们另外建一个连接,执行如下操作:

SET AUTOCOMMIT=0;

BEGIN;

SELECT actor_id FROM actor WHERE actor_id = 1 FOR UPDATE;

 

该查询会被挂起,直到第一个连接的事务提交释放锁时,才会执行(这种行为对于基于语句的复制(statement-based replication)是必要的)。
如上所示,当使用索引时,InnoDB会锁住它不需要的元组。更糟糕的是,如果查询不能使用索引,MySQL会进行全表扫描,并锁住每一个元组,不管是否真正需要。

[转自:http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html ]

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 行业技术 标签:

KeyWordInMyLife v1.1版

2012年5月11日 没有评论

界面模拟命令行的单词化日记系统

最新版本见:
http://blog.acmol.com/?page_id=1067
(当然我发这篇文章时最新版就是v1.1)
浏览器兼容性问题不少,准备随后慢慢解决的有:

  1. IE8输出任何语句之后再次输入时的输入文字格式不正确。
  2. Chrome,输入文字处有一个橙色边框影响美观,初始时光标不会闪烁

准备在下一版进行的改动,将命令行系统做好,做得可扩展…(似乎用在这么简单一个系统上不太值得,不过做着就是玩的)
还有就是这个系统再加上基本的删除日志功能。

<!--?php <br ?--> /**************************************
/*
/* name : WordDiary
/* author : zhangyuncong @ baidu
/* date : 2012-5-8
/* version : v1.1
/*
***************************************/
mysql_connect("localhost","host","password");
mysql_select_db("dbname");
mysql_query("set names utf8");

session_start();
$cmd=$_GET['cmd'];
$arr=explode(" ",$cmd,3);
$do=$arr[0];
function get_word_diary($year=0){
if($year) $result=mysql_query("select year(date) as year,month(date) as month,day(date) as day,diary from word_diary where year(date)='$year' order by year,month,day") or die(mysql_error());
else $result=mysql_query("select year(date) as year,month(date) as month,day(date) as day,diary from word_diary order by year,month,day") or die(mysql_error());
$ret=array();
while($row=mysql_fetch_row($result)){
$ret[$row[0]][$row[1]][$row[2]]=$row[3];
}
return $ret;
}
if($do=='show'){
echo '{"success":true,"message":"';
$year=$arr[1]?intval($arr[1]):date("Y");
$data=get_word_diary($year);
echo "
<p style="\0color: red\&quot;;">$year</p>
";
for($month = 12;$month != 0;$month--){
if($data[$year][$month]){
?&gt;

$total=count($data[$year][$month]); $cnt=0; foreach($data[$year][$month] as $day=&gt;$diary){ $cnt++;echo "";
if($cnt==5 &amp;&amp; $total!=$cnt) echo ""; } for(;$cnt%5;$cnt++)echo "";
?&gt;
<table>
<thead>
<tr>
<th colspan="&quot;5&quot;"><!--?php echo $month;?-->月</th>
</tr>
</thead>
<tbody>
<tr><!--?php <br ?-->
<td id="\&quot;diary-$year-$month-$day\&quot;"><span style="\0color: #65B042\&quot;;">[$day]</span><span style="\0color: #89BDFF\&quot;;">$diary</span></td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
<!--?php }}<br ?--> echo ""}";
exit(0);
}else if($do=='diary')
{
if(!$_SESSION['login']) {echo '{"success":false,"message":"You must login first"}' ;exit(0);}
if(count($arr)==2) {$date = date('Y-m-d');$diary=$arr[1];}
else {$date=$arr[1];$arr=explode(" ",$cmd,3);$diary=$arr[2];}
$res=mysql_query("select * from word_diary where date='$date'");
$row=mysql_fetch_row($res);
if($row[0]==0){
mysql_query("insert into word_diary values('$date','$diary')") or die('{"success":false,"message":"failed to add"}');
echo '{"success":true,"message":"ADDED"}';
}else{
mysql_query("update word_diary set diary='$diary' where date='$date'") or die('{"success":false,"message":"failed to Replace"}');;
echo '{"success":true,"message":"REPLACED"}';
}

exit(0);
}else if($do=='login'){
$salt="acmol";
$pass=$arr[1];
if(md5(md5($pass).$salt)=="8d8ce0bdec562f38dd3d5bda6649b63d"){
$_SESSION['login']=true;
echo "{"success":true,"message":"OK"}";
exit(0);
}else{
echo "{"success":false,"message":"Password Incorrect"}";
exit(0);
}
}else if($do=='initial'){
echo '{"success":true,"message":"Command can be used:
<ol>
	<li>show &lt;year&gt;
Show the date with the specific year.If the year is empty,it will show the diarys of this year.</li>
	<li>login &lt;password&gt;
To Login use password</li>
	<li>logout
To logout from diary management</li>
	<li>diary [date] &lt;diary_content&gt;
the &lt;diary_content&gt; should not contain any spaces. If the [date] is set , it will add modify the diary of the specific day,otherwise of today. Login needed.</li>
</ol>
"}';
exit(0);
}else if($do=='logout'){?&gt;{"success":true,"message":"logout success"}
<!--?php <br ?--> session_destroy();
exit(0);
}else if($do!=''){
?&gt;{"success":false,"message":"command not found"}
<!--?php <br ?--> exit(0);
}
?&gt;

<script type="text/javascript" src="assets/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">// <![CDATA[
  cmdQ=[];
  cmdCursor=0;
  User="Guest";
  var Console={
  Write:function(str){
   	$(".shown").html($(".shown").html()+str);
  },
  WriteLine : function (str){
  	 this.Write(str+"
");
  },
  InputComplete: function(){
	var txt=$(".edit").text();
  	this.WriteLine(txt);
	$(".edit").html("");
	return txt;
  },
  ShowTip:function(){
  	this.Write("["+User+"@acmol.com word-diary]$ ");
	$('.edit')[0].focus();
	$("body").animate({scrollTop:$(document).height()},function(){ $('.edit')[0].focus();});
  },
  SetInputLine:function(str){
	$('.edit').html(str);
	$('.edit')[0].focus();
  }
  };
  $(document).ready(function() {
    $(".edit").keydown(function(e){
		if(e.keyCode==13){
			cmdQ.push($(".edit").text());
			if(cmdQ.length>1000) cmdQ.shift();
			cmdCursor=cmdQ.length;
			$.getJSON("",{cmd:Console.InputComplete()},function(e){Console.WriteLine(e.message);Console.ShowTip();});
		}else if(e.keyCode==38){
			if(cmdCursor>0) cmdCursor--;
			e.preventDefault();
			Console.SetInputLine(cmdQ[cmdCursor]);
		}else if(e.keyCode==40){
			if(cmdCursor<cmdQ.length-1) cmdCursor++;
			e.preventDefault();
			Console.SetInputLine(cmdQ[cmdCursor]);
		}
	});
	$.getJSON("",{cmd:"show"},function(e){
		 Console.WriteLine(e.message);
		$.getJSON("",{cmd:"initial"},function(e){ 	Console.WriteLine(e.message);Console.ShowTip();});
	});

  });

// ]]></script>

<span class="shown">Word-Diary
-----Key words in my life

</span>

建表SQL如下:

CREATE TABLE `word_diary` (
`date` date NOT NULL,
`diary` varchar(15) collate utf8_bin NOT NULL,
PRIMARY KEY (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

代码中依赖了jquery-1.7.2

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

chrome扩展推荐:花密

2012年5月10日 没有评论

插件官网:http://flowerpassword.com/app/chrome

之前我就设想过一个chrome插件,用来解决各大网站各种密码泄漏的问题,具体原理与介绍见我的另一篇文章

写过上面文章之后,我也试着去想想如何实现,对之前的想法进行了一些修改,但是一直没去写插件,然后后来听同学说我的这个想法有人实现了,就把这个扩展下下来看了看~发现和我的设想的插件的功能与实现都简直一模一样~

下了下来一试,确实很好用~只是这个名字有点囧…

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

2012年Astar百度之星程序设计大赛官网介绍

2012年5月6日 没有评论

2012年Astar百度之星程序设计大赛官网介绍

 

大赛介绍

作为发掘中国大学生中最优秀的算法人才渠道,中国领先的互联网企业——百度公司每年都会举办一次Astar百度之星程序设计大赛,从2005年至今已成功举办了7届大赛。Astar百度之星程序设计大赛业已成为中国互联网行业最具知名度、最有影响力的大学生程序设计大赛。大赛已成为喜欢发掘最佳算法和数据结构,以解决各种挑战性问题的校园程序高手交流切磋的平台。参赛选手除国内高校计算机编程爱好者外,还包括美国、英国等全球知名高校的学生以及ACM大赛中国赛区知名院校的代表队,在充分扩展了国内参赛队员视野的同时,还增强了各校间的交流,得到全国各高校师生们的热烈欢迎。

Astar百度之星程序设计大赛也已经被视为国内程序员的“黄埔军校”和“造星工场”。从2005年至今,“百度之星”大赛累计累计参赛学生已经超过十多万名,无数编程人才通过大赛脱颖而出,优秀选手不仅能赢得丰厚奖金,大赛的获奖证书更相当于程序设计业界的“金领通行证”。入围最终决赛圈的选手,不仅获得百度的青睐,也成为众多知名IT互联网企业重金争夺的对象。

百度公司自成立起,一直致力于对大学生的科研创新与支持工作,并秉持“发现你的光芒”的人才观点,希望给予优秀的学生最合适的发展平台和空间,让学生能充分发挥出自己的才能和价值。在大赛中脱颖而出的选手将获得百度公司的校园招聘绿色通道,直接获得加盟百度的优先通行证,为广大学子所青睐。

2012年Astar百度之星程序设计大赛在初赛前增加一场资格赛,邀请全球范围的同学一起挑战吉尼斯最大规模编程比赛。除传统Astar算法外,还将新设公益编程比赛,解决大学生共同面临的问题,所有在校的计算机爱好者同学将可一试身手。

 

大赛流程及时间

1. Astar资格赛(吉尼斯挑战赛)—→初赛(算法PK)—→复赛(算法PK)—→总决赛(算法PK)

5月29日~5月31日 6月2、3日 6月10、17日 7月底8月初

2. 公益编程比赛,2012年5月7日~6月30日

 

注册报名:2012年5月7日0时至5月31日24时

只要注册报名就有机会参加资格赛,赢得奖品。如果你是一个不会编程的同学,注册后,我们会有悉心的指导教程,让你快速上手入门。

 

百度之星资格赛:2012年5月29日0时至5月31日24时

资格赛作为第一轮粗筛选的比赛,所有注册的同学都可以参加。资格赛共计72小时,同学们可以任选时间开始比赛,选做任意一题或者多题,系统将进行在线编译及评判,只要通过任意一题的评判即可获得初赛资格。最早做出全部资格赛题目的同学,可获得New iPad一部,所以资格赛开赛后一定要早早开始比赛噢!另外,每个同学每做出一题(每题限一次),都将得到一个“过题编号”,获得抽奖百度易手机、度度熊以及百度BAE平台邀请码和百度网盘15G超大存储空间的机会,做题越多,机会越大!

 

百度之星初赛:2012年6月2日、6月3日10:00Am~12:00Pm

本次大赛的初赛的初赛采取在线答题、编译,离线判题的形式,选手报名后,可以在6月2日、6月3日任选一天参加比赛,也可选择两场都参加。针对每题,交题后,系统将给出程序编译是否正确的结果,但不会给出程序是否通过全部测试数据的评价;当场比赛结束后,所有选手的针对每题所写的程序将被离线评判,每题根据程序通过测试数据的数目计算得分(如某题通过测试数据组数为N,总测试数据数为M,当前题目得分为[2^(N/M)]*100)。每场初赛根据单场所有题目总分计算成绩,选出当场成绩在前400名的选手进入复赛(第一场已经进入复赛的选手参加第二场比赛如果再次晋级,将被不在第二场参与排名)。

 

百度之星复赛:2012年6月10、17日

本次大赛的初赛的初赛采取在线答题、编译,离线判题的形式,选手报名后,可以在6月10日、6月17日任选一天参加比赛,也可选择两场都参加。具体判题方式与初赛一致。每场初赛根据单场所有题目总分计算成绩,选出当场成绩在前25名的选手进入复赛(第一场已经进入复赛

的选手参加第二场比赛如果再次晋级,将被不在第二场参与排名)。

 

公益编程比赛:2012年5月7日0时至6月30日24时

公益编程比赛,解决全国大学生共同面临的问题,全国高校所有计算机爱好者同学均可一试身手。

1. 关于参赛:

1) 请从“解决校园需求”、“解决社会公益问题”、“解决能源问题”或“解决交通问题”这4个方面任选其一。也可以另选一个其他方面的问题提交编程应用作品,程序的形式、运行环境不限。

2) 参赛同学可以凭身份证号码获得一个百度网盘邀请码,6月30日比赛结束前,将作品上传到百度网盘中,并只需要到官网给出分享链接供全国广大学生网友下载使用,并投票评选最佳应用程序。

3) 对于网络应用类的作品提交,最终优秀的作品给予百度应用引擎(Baidu App Engine,缩写BAE)平台账号,赠送1 – 2年的使用开支。

2. 关于评选:

1) 5月7日~6月30日,选手提交作品,7月1日 – 7月20日,学生下载应用及网络投票,与总决赛一同发布获奖名单。

2) 根据程序下载量和人气投票,评选出最具人气应用程序前三名,每人奖励一台New iPad。

欢迎参加公益编程比赛的同学积极参加百度之星资格赛,向百度之星大牛们发起挑战!

 

百度之星现场总决赛:2012年7月末

晋级现场的算法比拼,让人心动的夏令营体验!我们为每位决赛赛手免费提供旅行膳宿,妥善安排往返机场及比赛现场的接送,参加百度组织的相关活动,并为每位赛手购买总决赛期间的人身意外伤害保险。

 

大赛奖项设置

1. 百度之星总决赛一等奖1名 30000元 人民币

2. 百度之星总决赛二等奖2名 15000元 人民币

3. 百度之星总决赛三等奖3名 5000元 人民币

4. 百度之星晋级奖 百度还将会邀请晋级的50位赛手至北京,参加为期5天的总决赛,并获得度度熊和证书。

5. 百度之星参与奖 复赛成绩前500名的选手将获得大赛限量纪念版T恤一件及大赛证书,前200名选手可获得百度BAE平台邀请码各一个。

6. 幸运奖 凡报名参加比赛的同学,就有机会获得百度易手机(5台)以及百度双肩包(100个)和50个百度BAE平台邀请码。

7. 百度之星资格赛吉尼斯挑战纪念奖:2012年百度之星将挑战吉尼斯最大规模编程大赛记录,挑战成功将为每位参与挑战赛的选手颁发大赛纪念电子证书,每位选手可下载打印。同时抽取1000名幸运同学每人赠送Astar吉尼斯挑战纪念T恤一件。

8. 公益编程比赛优胜奖3名 每人一部New iPad。

9. 公益编程比赛优秀奖50名 网络应用类作品每人可获得一个百度BAE平台邀请码,所有获奖者均获得百度之星公益编程大赛证书。

 

百度之星大赛入围决赛和复赛的选手将自动进入百度公司人才库,将有机会优先参与百度实习计划,接受技术牛人指导职业发展,接触搜索引擎核心技术,并在百度公司的校园招聘活动享受“绿色通道”待遇。

 

公益编程比赛中涌现出来的优秀选手将自动进入百度公司人才库,将有机会优先参与百度实习计划,接受技术牛人指导,接触百度核心技术,并在百度公司的校园招聘活动享受尖子生待遇。

 

线下培训宣讲会

我们在全国有10场的百度之星线下培训宣讲课,指导同学如何报名参加百度之星大赛,还有往届选手分享如何取得大赛好成绩。现场有精美礼品及更多百度BAE平台邀请码等着你,欢迎同学积极参加!

 

线路 日期 星期 时间 城市 宣讲学校 宣讲场地
线路一 5月7日 星期一 北京 清华大学
5月9日 星期三 北京 北京邮电大学
5月10日 星期四 郑州 郑州大学
5月14日 星期一 成都 电子科技大学
5月16日 星期三 西安 西安电子科技大学
线路二 5月10日 星期四 南京 南京大学
5月12日 星期六 广州 中山大学
5月14日 星期一 长沙 湖南大学
5月16日 星期三 武汉 华中科技大学
5月19日 星期六 杭州 杭州电子科技大学

 

参赛资格与要求

由赛手个人独立完成全部题目,无任何作弊和欺诈行为。

除百度现职员工、现职实习生和命题委员会成员外都有资格报名参赛,无报名费用。

注:每人只能报名一次,填写信息需完整准确。

 

报名参赛

登录astar.baidu.com,点击“我要参赛”栏目,在线注册报名,从5月7日起即可参加公益编程比赛,5月29日至5月31日可参加百度之星资格赛。

 


该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 未分类 标签:

【原创】你肯定也这么苦逼,我用helloworld保证

2012年5月5日 没有评论

以上内容纯属为了牢骚而牢骚的贴子,其实倒是挺喜欢有朋友找着让帮忙的,即使许多时候帮不上忙~~

—————————-

搞计算机的确实都是苦逼,其实,工资了、工作压力了什么的感觉还好,最他妹苦逼的事就是别人让你帮忙修windows还不让格盘,让你帮忙做ppt的时候……

你妹的都是,哥说了哥搞计算机的不学这些,哥学的是做软件,不是用别人软件,说完自己都感觉没底气……你他妹的这么说,谁信啊……你基本上能想象到对方在想什么:“不想帮忙算了,搞计算机的连把word页码从第三页开始标都不会,你他妹骗谁呢”

于是,你只好百度了那么一下给他说说怎么搞,但大多数时候,你会遇到以下情形:
你百度了一下花了几秒钟,但想给对方他妹的讲明白怎么做得花几个小时…
你:“你打开U盘,看看里面有木有一个autorun.inf”
你妹的:“好,我看看……呃,没有啊”
你:“没有?哦,可能是隐藏文件没显示,打开窗口上面的文件夹菜单,然后选项,然后然后&#*!%”
你妹的:“呃,找不到*&在哪”
你:找不到?怎么会呢?就在%^&旁边啊…呃,你把截个图发过来
你妹的:好…%^&
$%^&*()_++(*&^%$#@#$%^&*(*&^%$#$%^&*……
你:“唉,好吧,我给你写个脚本你运行下就显示隐藏文件了”然后写个脚本发过去……
你:“好了没有,找到那个autorun.inf了没有”
你妹的:“等等,这些代码怎么用啊?”
你:“&#*!%”最终你只好打包发过去一个叫做能直接双击的东东……然后问:“看到那个autorun.inf没有?”
你妹的:“多了一堆东西,但是没有你说的什么.inf啊”
你:“不应该啊,刚你发的图片来看,你U盘图标都变了,应该有啊”
然后一番排查……
最终一个小时后你意识到一件事,这家伙可能没显示文件扩展名,于是问:“你在看看你优盘里有没有一个叫autorun的,后面没那个inf的也行”
你妹的:“好,我看下……有个叫autorun的……然后呢”
…………
…………
…………
最终,你根据autorun知道了这个病毒你以前见过,杀毒其实不难,只用改改注册表,安全模式一下,删几个东西就好了,但是,要让你给他说清楚怎么查杀,还不如杀了你来得直接,然后你开始说:“这个病毒很牛逼的,前几天还攻克了美国服务中心的linux服务器,很难手工杀,我也是学了好久才刚从高手那里学会怎么杀掉他的,不容易给你说懂啊,很复杂,其实你还是重装系统吧……”
你妹的:“这么厉害的病毒啊”,现在你基本上能感受到对方的敬仰了,特别是说出linux之后,“那,我还是重装吧,你能教我怎么装吗?高手”
…………
…………
然后后面就是你由生以来第一次装机的悲催经历……

然后,又一个电话过来了,“我想买个笔记本,戴耳的和脸想的哪个好?我想着你学计算机的应该比较了解这个的…”

 

……

——————————————————————————————————————————————————————–

再次重申,谢谢那些看得起我问我问题的同学~只是,我希望你明白我,有时候不是我不想帮忙而是那一方面确实我没接触过

相信许多人都会有我这种感触的

该文章为acmol所有,转载请指明出处:http://blog.acmol.com

分类: 娱乐 标签: