chaosuper85

C++博客 首页 新随笔 联系 聚合 管理
  118 Posts :: 0 Stories :: 3 Comments :: 0 Trackbacks

#

http://www.iciba.com/
posted @ 2010-02-05 16:58 chaosuper 阅读(48) | 评论 (0)编辑 收藏

Debian/Ubuntu Linux下内核编程者必备的几件法宝
链接 : http://zhoulifa.bokee.com/index.html
如果你想要升级你的Debian/Ubuntu Linux内核,或者你希望为内核开发新的模块,或者您要为某个硬件写新的驱动程序……这一切都涉及到Debian/Ubuntu Linux内核编程。 作为一个内核编程者,有那么几个软件是你必须要有的,看作是你进行内核编程的几件法宝吧,下面我一一列举出来: 1、gcc 大名鼎鼎的gcc我想没有人不知道的吧?它是任何编程者必然要先安装的一个武器了。不过一般如果你是安装的Debian系统,应该已经默认安装了的。要是Ubuntu你就安装一下吧,安装方法嘛,就是输入: apt-get install gcc 2、make 如果你实实在在地写过有用的程序,你一定输入过make clean、make、make install等命令的,make是一个源代码维护工具,它能自动检测出需要重新编译的源文件并根据你设定的编译规则去重新编译程序。这里也不多说,如果不了解的朋友就google一下吧。不过一般如果你是安装的Debian系统,应该已经默认安装了的。要是Ubuntu你就安装一下吧,安装方法一样,输入: apt-get install make 3、kernel-source 从这个包的名称上已经知道了,这是内核源码包。你可以apt-cache search kernel-source搜索到内核源代码包,并用uname -r命令查看到当前系统内核版本,然后用apt-get install kernel-source-xxxx来安装和你内核版本一致的内核源代码包。 但我并不建议你这样做,因为大多数发行版的Linux的内核源代码包并不是和你从kernel.org上下载来的完全一致,应该是经过发行者们修改优化过的包,虽然发行版的制作者们花了心血在上面,但对我们编程者来说这并不是件好事,因为大多发行版的源代码包缺少某些必要的头文件和某些有用的脚本程序,这会导致我们在编写内核模块时遇到麻烦,比如编译时可能会报错说某个头文件找不到,又可能报错说某个脚本程序不存在啦。 如果你直接去kernel.org上下载一个新的内核来编译升级你的内核,并在此基础上进行内核编程可能会省事一些,至少我后面讲到的这些包你都可以不用安装了,把KERNEL_DIR变量设置为你内核源代码包的位置就够了。 在这里还是以Debian 3.1、内核2.6.8-2-386为基础来教大家准备内核编程环境吧。那么你依次用这几个命令来安装kernel-source包吧。 apt-cache search kernel-source uname -r apt-get install kernel-source-xxxx 注:如果你不想重新编译内核,内核源代码包kernel-source是完全可以不下载来的。 4、kernel-headers 这是内核源代码头文件包,不管你是要进行内核模块开发还是进行驱动程序开发,这个包都是必须要安装的。因为作为一个内核模块编写者,通常会调用内核里的一些东西,比如内核头文件,内核数据结构申明等。它里面包含了一些关键的内核头文件。否则在编译内核时会报类似下面的错误: HOSTCC scripts/basic/fixdep scripts/basic/fixdep.c:105:23: error: sys/types.h: 没有那个文件或目录 输入如下命令来安装吧: apt-cache search kernel-headers uname -r apt-get instakk kernel-headers-xxxx 注:在Ubuntu下,好象这个包的前面都加上了linux-,从而变成了linux-kernel-headers。 如果之前没有安装过kernel-kbuild包,安装此包的过程中会安装kernel-kbuild包,这个包在下面介绍。 关于本文档: /********************************************************************* *filename: Debian/Ubuntu Linux下内核编程者必备的几件法宝 *purpose: 记录Linux内核开发者必备的几个软件包 *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 *date time:2006-07-01 22:50:00 *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 * 但请遵循GPL *********************************************************************/ 5、kernel-kbuild 这个包是用来编译内核模块的,下载安装这个包后会发现在/usr/src目录下多了一个kernel-kbuild-xxxx开头的目录,下面只有scripts一个目录,显然这是用来编译内核模块的一些脚本程序。安装方法一样: apt-cache search kernel-kbuild uname -r apt-get install kernel-kbuild-xxxx 注:你也会发现,在上面安装kernel-headers包后,/usr/src/kernel-headers-xxxx目录下有个scripts目录,其实是到/usr/src/kernel-kbuild-xxxx目录下的scripts的一个链接。 6、build-essential 这个包包含一个在建立deb包过程中起关键作用的包的信息列表,如果你不想建立deb包你就不需要安装此表,如果需要生成deb包就最好安装一下这个包吧。安装方法: apt-get install build-essential 7、kernel-package 如果你想把内核镜像做成一个deb包来用,那么必须用安装这个包了。也就是说只有安装了这个软件包你才能有make-kpkg命令可用。安装方法一样了: apt-get install kernel-package 8、initrd-tools 如果你想制作启动过程的initrd镜像,则这个包是必不可少的。安装了这个包之后才有mkinitrd命令可用的。安装方法: apt-get instakk initrd-tools 最后来一个内核模块编程示例吧: 假设你编写了一个内核模块程序,源代码如下: /* hello.c */ #include #include #include static int hello_init(void) { printk(KERN_ALERT "Hello, linux kernel module\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, I've created a linux kernel module sucessfully\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); 你需要这此源程序编写一个makefile,内容如下: #Makefile for hello.c file # KERNEL_DIR:=/usr/src/linux obj-m:=hello.o default: $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules clean: $(RM) .*.cmd *.mod.c *.o *.ko -r .tmp 注意:这里的KERNEL_DIR是指内核源代码头文件所在目录的上一级目录,通常就是指内核源代码目录。该目录一般包括有arch,drivers,fs,include,init,ipc,kernel,lib,mm,net,scripts,usr,sound,security等目录。 在本示例中,/usr/src/linux是一个链接,指向了/usr/src/kernel-headers-2.6.8-3目录。 编写好makefile后就可以输入make命令生成hello.ko内核模块了,然后你可以用: insmode hello.ko 命令来加入内核模块,然后用: rmmod hello 来删除内核模块。 当然,操作过程中,你可以用dmesg命令来查看运行结果。
posted @ 2010-02-05 14:10 chaosuper 阅读(155) | 评论 (0)编辑 收藏

Linux 2.6内核中提高网络I/O性能的新方法epoll 正如我昨天在“Linux下各类TCP网络服务器的实现源代码”(http://zhoulifa.bokee.com/5345930.html)一文中提到的那样,I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数。 感谢chinaunix.net上朋友safedead(http://bbs.chinaunix.net/viewpro.php?uid=407631)提醒,我今天仔细研究了一下,证实了在2.6内核中的新的I/O技术epoll。 1、为什么select是落后的? 首先,在Linux内核中,select所用到的FD_SET是有限的,即内核中有个参数__FD_SETSIZE定义了每个FD_SET的句柄个数,在我用的2.6.15-25-386内核中,该值是1024,搜索内核源代码得到: include/linux/posix_types.h:#define __FD_SETSIZE 1024 也就是说,如果想要同时检测1025个句柄的可读状态是不可能用select实现的。或者同时检测1025个句柄的可写状态也是不可能的。 其次,内核中实现select是用轮询方法,即每次检测都会遍历所有FD_SET中的句柄,显然,select函数执行时间与FD_SET中的句柄个数有一个比例关系,即select要检测的句柄数越多就会越费时。 当然,在前文中我并没有提及poll方法,事实上用select的朋友一定也试过poll,我个人觉得select和poll大同小异,个人偏好于用select而已。 /************关于本文档******************************************** *filename: Linux 2.6内核中提高网络I/O性能的新方法epoll *purpose: 补充“Linux下各类TCP网络服务器的实现源代码”一文的不足之处 *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com) Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言 *date time:2006-07-06 22:30:00 *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途 * 但请遵循GPL *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力 *********************************************************************/ 2、2.6内核中提高I/O性能的新方法epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll。要使用epoll只需要这三个系统调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。 当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44) 以下文章转自滕昱的Web Log http://mechgouki.spaces.msn.com/blog/PersonalSpace.aspx/*********************************引用开始******************************/ Linux2.6内核epoll介绍---我的blog 2005/3/30 [作者]:滕昱,2005/3/30,0.1版本 [版权声明]:此文档遵循GNU自由文档许可证(GNU Free Documentation License).任何人可以自由复制,分发,修改,不过如果方便,请注明出处和作者:) (1)导言: 首先,我强烈建议大家阅读Richard Stevens著作《TCP/IP Illustracted Volume 1,2,3》和《UNIX Network Programming Volume 1,2》。虽然他离开我们大家已经5年多了,但是他的书依然是进入网络编程的最直接的道路。其中的3卷的《TCP/IP Illustracted》卷1是必读-如果你不了解tcp协议各个选项的详细定义,你就失去了优化程序重要的一个手段。卷2,3可以选读一下。比如卷2 讲解的是4.4BSD内核TCP/IP协议栈实现----这个版本的协议栈几乎影响了现在所有的主流os,但是因为年代久远,内容不一定那么vogue. 在这里我多推荐一本《The Linux Networking Architecture--Design and Implementation of Network Protocols in the Linux Kernel》,以2.4内核讲解Linux TCP/IP实现,相当不错.作为一个现实世界中的实现,很多时候你必须作很多权衡,这时候参考一个久经考验的系统更有实际意义。举个例子,linux内核中sk_buff结构为了追求速度和安全,牺牲了部分内存,所以在发送TCP包的时候,无论应用层数据多大,sk_buff最小也有272的字节. 其实对于socket应用层程序来说,《UNIX Network Programming Volume 1》意义更大一点.2003年的时候,这本书出了最新的第3版本,不过主要还是修订第2版本。其中第6章《I/O Multiplexing》是最重要的。Stevens给出了网络IO的基本模型。在这里最重要的莫过于select模型和Asynchronous I/O模型.从理论上说,AIO似乎是最高效的,你的IO操作可以立即返回,然后等待os告诉你IO操作完成。但是一直以来,如何实现就没有一个完美的方案。最著名的windows完成端口实现的AIO,实际上也是内部用线程池实现的罢了,最后的结果是IO有个线程池,你应用也需要一个线程池...... 很多文档其实已经指出了这带来的线程context-switch带来的代价。 在linux 平台上,关于网络AIO一直是改动最多的地方,2.4的年代就有很多AIO内核patch,最著名的应该算是SGI那个。但是一直到2.6内核发布,网络模块的AIO一直没有进入稳定内核版本(大部分都是使用用户线程模拟方法,在使用了NPTL的linux上面其实和windows的完成端口基本上差不多了)。2.6内核所支持的AIO特指磁盘的AIO---支持io_submit(),io_getevents()以及对Direct IO的支持(就是绕过VFS系统buffer直接写硬盘,对于流服务器在内存平稳性上有相当帮助)。 所以,剩下的select模型基本上就是我们在linux上面的唯一选择,其实,如果加上no-block socket的配置,可以完成一个"伪"AIO的实现,只不过推动力在于你而不是os而已。不过传统的select/poll函数有着一些无法忍受的缺点,所以改进一直是2.4-2.5开发版本内核的任务,包括/dev/poll,reltime signal等等。最终,Davide Libenzi开发的epoll进入2.6内核成为正式的解决方案 (2)epoll的优点 <1>支持一个进程打开大数目的socket描述符(FD) select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。 <2>IO效率不随FD数目增加而线性下降 传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是"活跃"的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对"活跃"的socket进行操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个"伪"AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的---比如一个高速LAN环境,epoll并不比select/poll有什么效率,相反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。 <3>使用mmap加速内核与用户空间的消息传递。 这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。 <4>内核微调 这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小--- 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。 (3)epoll的使用 令人高兴的是,2.6内核的epoll比其2.5开发版本的/dev/epoll简洁了许多,所以,大部分情况下,强大的东西往往是简单的。唯一有点麻烦是epoll有2种工作方式:LT和ET。 LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表. ET (edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认。 epoll只有epoll_create,epoll_ctl,epoll_wait 3个系统调用,具体用法请参考http://www.xmailserver.org/linux-patches/nio-improve.html , 在http://www.kegel.com/rn/也有一个完整的例子,大家一看就知道如何使用了 (4)Leader/follower模式线程pool实现,以及和epoll的配合 .....未完成,主要是要避免过多的epoll_ctl调用,以及尝试使用EPOLLONESHOT加速...... (5)benchmark .......未完成 /*********************************引用结束******************************/ 3、epoll的使用方法 这是epoll的man手册提供的一个例子,这段代码假设一个非阻塞的socket监听listener被建立并且一个epoll句柄kdpfd已经提前用epoll_create建立了: struct epoll_event ev, *events; for(;;) { nfds = epoll_wait(kdpfd, events, maxevents, -1);/*wait for an I/O event. All notes here added by zhoulifa(http://zhoulifa.bokee.com) on 2006-7-6 22:10:00*/ for(n = 0; n < nfds; ++n) { if(events[n].data.fd == listener) {/*if listen socket has an I/O, accept the new connect*/ client = accept(listener, (struct sockaddr *) &local, &addrlen); if(client < 0){ perror("accept"); continue; } setnonblocking(client); ev.events = EPOLLIN | EPOLLET;/*EPOLLIN-available for read*/ ev.data.fd = client; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {/*add the new socket into the epoll file descriptors*/ fprintf(stderr, "epoll set insertion error: fd=%d\n", client); return -1; } } else do_use_fd(events[n].data.fd);/*read from a socket which has data come*/ } } 4、epoll使用方法示意代码 以下代码由chinaunix.net上BBS用户safedead(http://bbs.chinaunix.net/viewpro.php?uid=407631)提供: static int s_epfd;//epoll描述字 {//初始化epoll &nsp; struct epoll_event ev; //设置epoll s_epfd = epoll_create(65535); {//这个过程可以循环以便加入多个LISTEN套接字进入epoll事件集合 //服务器监听创建 rc = listen();//listen参数这里省略 //加入epoll事件集合 ev.events = EPOLLIN; ev.data.fd = rc; if (epoll_ctl(s_epfd, EPOLL_CTL_ADD, rc, &ev) < 0) { fprintf(stderr, "epoll set insertion error: fd=%d", rc); return(-1); } } } {//epoll事件处理 int i, nfds, sock_new; struct epoll_event events[16384]; for( ; ; ) { //等待epoll事件 nfds = epoll_wait(s_epfd, events, 16384, -1); //处理epoll事件 for(i = 0; i < nfds; i++) { //events[i].data.fd是epoll事件中弹出的套接字 //接收连接 sock_new = accept(events[i].data.fd);//accept其它参数这里省略了 if(0 > sock_new) { fprintf(stderr, "接收客户端连接失败\n"); continue; } } } } 对照safedead和前面的一份代码,我想大家一定是明白了的。
posted @ 2010-02-05 14:06 chaosuper 阅读(143) | 评论 (0)编辑 收藏

select, poll和epoll的区别(转载) select()系统调用提供一个机制来实现同步多元I/O: #include #include #include int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_CLR(int fd, fd_set *set); FD_ISSET(int fd, fd_set *set); FD_SET(int fd, fd_set *set); FD_ZERO(fd_set *set); 调用select()将阻塞,直到指定的文件描述符准备好执行I/O,或者可选参数timeout指定的时间已经过去。 监视的文件描述符分为三类set,每一种对应等待不同的事件。readfds中列出的文件描述符被监视是否有数据可供读取(如果读取操作完成则不会阻塞)。writefds中列出的文件描述符则被监视是否写入操作完成而不阻塞。最后,exceptfds中列出的文件描述符则被监视是否发生异常,或者无法控制的数据是否可用(这些状态仅仅应用于套接字)。这三类set可以是NULL,这种情况下select()不监视这一类事件。 select()成功返回时,每组set都被修改以使它只包含准备好I/O的文件描述符。例如,假设有两个文件描述符,值分别是7和9,被放在readfds中。当select()返回时,如果7仍然在set中,则这个文件描述符已经准备好被读取而不会阻塞。如果9已经不在set中,则读取它将可能会阻塞(我说可能是因为数据可能正好在select返回后就可用,这种情况下,下一次调用select()将返回文件描述符准备好读取)。 第一个参数n,等于所有set中最大的那个文件描述符的值加1。因此,select()的调用者负责检查哪个文件描述符拥有最大值,并且把这个值加1再传递给第一个参数。 timeout参数是一个指向timeval结构体的指针,timeval定义如下: #include struct timeval { long tv_sec; /* seconds */ long tv_usec; /* 10E-6 second */ }; 如果这个参数不是NULL,则即使没有文件描述符准备好I/O,select()也会在经过tv_sec秒和tv_usec微秒后返回。当select()返回时,timeout参数的状态在不同的系统中是未定义的,因此每次调用select()之前必须重新初始化timeout和文件描述符set。实际上,当前版本的Linux会自动修改timeout参数,设置它的值为剩余时间。因此,如果timeout被设置为5秒,然后在文件描述符准备好之前经过了3秒,则这一次调用select()返回时tv_sec将变为2。 如果timeout中的两个值都设置为0,则调用select()将立即返回,报告调用时所有未决的事件,但不等待任何随后的事件。 文件描述符set不会直接操作,一般使用几个助手宏来管理。这允许Unix系统以自己喜欢的方式来实现文件描述符set。但大多数系统都简单地实现set为位数组。FD_ZERO移除指定set中的所有文件描述符。每一次调用select()之前都应该先调用它。 fd_set writefds; FD_ZERO(&writefds); FD_SET添加一个文件描述符到指定的set中,FD_CLR则从指定的set中移除一个文件描述符: FD_SET(fd, &writefds); /* add 'fd' to the set */ FD_CLR(fd, &writefds); /* oops, remove 'fd' from the set */ 设计良好的代码应该永远不使用FD_CLR,而且实际情况中它也确实很少被使用。 FD_ISSET测试一个文件描述符是否指定set的一部分。如果文件描述符在set中则返回一个非0整数,不在则返回0。FD_ISSET在调用select()返回之后使用,测试指定的文件描述符是否准备好相关动作: if (FD_ISSET(fd, &readfds)) /* 'fd' is readable without blocking! */ 因为文件描述符set是静态创建的,它们对文件描述符的最大数目强加了一个限制,能够放进set中的最大文件描述符的值由FD_SETSIZE指定。在Linux中,这个值是1024。本章后面我们还将看到这个限制的衍生物。 返回值和错误代码 select()成功时返回准备好I/O的文件描述符数目,包括所有三个set。如果提供了timeout,返回值可能是0;错误时返回-1,并且设置errno为下面几个值之一: EBADF 给某个set提供了无效文件描述符。 EINTR 等待时捕获到信号,可以重新发起调用。 EINVAL 参数n为负数,或者指定的timeout非法。 ENOMEM 不够可用内存来完成请求。 -------------------------------------------------------------------------------------------------------------- poll()系统调用是System V的多元I/O解决方案。它解决了select()的几个不足,尽管select()仍然经常使用(多数还是出于习惯,或者打着可移植的名义): #include int poll (struct pollfd *fds, unsigned int nfds, int timeout); 和select()不一样,poll()没有使用低效的三个基于位的文件描述符set,而是采用了一个单独的结构体pollfd数组,由fds指针指向这个组。pollfd结构体定义如下: #include struct pollfd { int fd; /* file descriptor */ short events; /* requested events to watch */ short revents; /* returned events witnessed */ }; 每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域。revents域是文件描述符的操作结果事件掩码。内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。合法的事件如下: POLLIN 有数据可读。 POLLRDNORM 有普通数据可读。 POLLRDBAND 有优先数据可读。 POLLPRI 有紧迫数据可读。 POLLOUT 写数据不会导致阻塞。 POLLWRNORM 写普通数据不会导致阻塞。 POLLWRBAND 写优先数据不会导致阻塞。 POLLMSG SIGPOLL消息可用。 此外,revents域中还可能返回下列事件: POLLER 指定的文件描述符发生错误。 POLLHUP 指定的文件描述符挂起事件。 POLLNVAL 指定的文件描述符非法。 这些事件在events域中无意义,因为它们在合适的时候总是会从revents中返回。使用poll()和select()不一样,你不需要显式地请求异常情况报告。 POLLIN | POLLPRI等价于select()的读事件,POLLOUT | POLLWRBAND等价于select()的写事件。POLLIN等价于POLLRDNORM | POLLRDBAND,而POLLOUT则等价于POLLWRNORM。 例如,要同时监视一个文件描述符是否可读和可写,我们可以设置events为POLLIN | POLLOUT。在poll返回时,我们可以检查revents中的标志,对应于文件描述符请求的events结构体。如果POLLIN事件被设置,则文件描述符可以被读取而不阻塞。如果POLLOUT被设置,则文件描述符可以写入而不导致阻塞。这些标志并不是互斥的:它们可能被同时设置,表示这个文件描述符的读取和写入操作都会正常返回而不阻塞。 timeout参数指定等待的毫秒数,无论I/O是否准备好,poll都会返回。timeout指定为负数值表示无限超时;timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符,但并不等待其它的事件。这种情况下,poll()就像它的名字那样,一旦选举出来,立即返回。 返回值和错误代码 成功时,poll()返回结构体中revents域不为0的文件描述符个数;如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1,并设置errno为下列值之一: EBADF 一个或多个结构体中指定的文件描述符无效。 EFAULT fds指针指向的地址超出进程的地址空间。 EINTR 请求的事件之前产生一个信号,调用可以重新发起。 EINVAL nfds参数超出PLIMIT_NOFILE值。 ENOMEM 可用内存不足,无法完成请求。 -------------------------------------------------------------------------------------------------------------- 以上内容来自《OReilly.Linux.System.Programming - Talking.Directly.to.the.Kernel.and.C.Library.2007》 -------------------------------------------------------------------------------------------------------------- epoll的优点: 1.支持一个进程打开大数目的socket描述符(FD) select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的 Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。 2.IO效率不随FD数目增加而线性下降 传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是"活跃"的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对"活跃"的socket进行操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个"伪"AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的---比如一个高速LAN环境,epoll并不比select/poll有什么效率,相反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。 3.使用mmap加速内核与用户空间的消息传递。 这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。 4.内核微调 这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小--- 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。
posted @ 2010-02-03 22:45 chaosuper 阅读(241) | 评论 (0)编辑 收藏

#include
#include
/* 字符串的所有字符排列函数,用已知字符串s中的所有字符,生成由其中n个字符组成的所有字符排列 */
#define N 20
char w[N];
perm(int n, char *s)
{
char s1[N];
int i;
if(n<1)
printf("%s\n",w); /* 一个排列生成输出 */
else
{
strcpy(s1,s); /* 保存本层次可使用的字符 */
for(i=0;*(s1+i);i++) /* 依次选本层次可用字符 */
{
*(w+n-1)=*(s1+i);/* 将选用字符填入正在生成的字符排列中 */
*(s1+i)=*s1;
*s1=*(w+n-1);
perm(n-1,s1+1); /* 递归 */
}
}
}
int main()
{
int n=2;
char s[N];
w[n]='\0';
printf("This is a char permutation program!\nPlease input a string:\n");
scanf("%s",s);
puts("\nPlease input the char number of permuted:\n");
scanf("%d",&n);
puts("The permuted chars are:\n");
perm(n,s);
puts("\nPress any key to quit...");
return 0;
}
posted @ 2010-02-03 21:03 chaosuper 阅读(100) | 评论 (0)编辑 收藏

     摘要: 学习链接 http://manual.luaer.cn/ -------------------------------------------------------------------------------- Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes ...  阅读全文
posted @ 2010-01-30 20:50 chaosuper 阅读(2857) | 评论 (0)编辑 收藏

如果你喜欢编程,那么你真是受到了上天的眷顾。你是非常幸运的少数人之一,能够以自己喜欢的事谋生。大多数人没有这么幸运。你认为理所当然的观念“热爱你的工作”,其实是一个很现代的概念。通常的看法是,工作是一种让人很不开心的事,你为了拿工资才不得不去上班。你工作的目的是为了攒下钱去干那些自己真正喜欢干的事,但是前提是你得等到65岁退休之后才行,而且还有不少条件。条件一,你的积蓄必须足够多;条件二,你没有老到走不动,你还有体力去干那些事情;条件三,你喜欢的事情不需要用到脆弱的膝盖、昏花的视力,也不要求你走上一里地不喘气,等等。 我刚才说到哪里了?对了,我要提建议。 毕业前练好写作 如果不是Linus Torvalds不断地散布福音,请问Linux操作系统会成功吗?虽然他是一个非常聪明的计算机天才,但是Linux吸引来全世界一大批志愿者的真正原因却是Linus Torvalds的表达能力。他通过电子邮件和邮件列表用书面形式传播自己的想法,最终引起了所有人的注意。 你听说过现在风靡一时的“极限编程[ ] ”(Extreme Programming)吗?我在这个地方不谈我对极限编程的看法,我只说如果你听过这个词,那么原因就是它的倡导者都是一些非常有才华的作家和演说家。 即使我们缩小范围,将目光局限在任何一个软件开发团体中,你也会发现该团体中最有权势和影响力的程序员正是那些表达能力强的程序员,他们无论是做书面表达还是做口头表达,都能够清晰、自如、具有说服力地传达观点。此外,长得高也有助于提升影响力,不过这个不取决于你。 一个普通程序员与一个优秀程序员的区别,不在于他们懂得的编程语言谁多谁少,也不在于他们喜欢用Python语言还是喜欢用Java语言,而在于他们能否与他人交流思想。如果你能说服其他人,你的力量就可以得到放大。如果你能写出清晰的注释和技术规格说明书,其他程序员就能够理解你的代码,因此他们就能在自己的代码中使用,而不必重写。如果你做不到这一点,你的代码对其他人就没有价值。如果你能为最终用户写出清晰的使用手册,其他人就能明白你的代码是用来干什么的,这是唯一让别人明白你的代码有何价值的方法。SourceForge[ ]上有许多优美的、有用的代码,但是它们都像被埋葬了一样,根本没人来用,原因就是它们的作者没有写好使用说明(或者压根就没写)。这样一来就没有人知道他们的成果,他们杰出的代码就衰亡了。 如果一个程序员不会用英语写作、没有良好的写作能力,我就不会雇他。如果你能写,不管你去哪家公司工作,你很快就会发现写作技术文档的任务会落到你头上,这意味着你已经开始在放大自己的影响力了,管理层正在注意到你。 大学里有些课程被公认为“写作密集型”(writing intensive)课程,这就是说为了拿到学分,你必须写作多得可怕的文字。一定要去上这样的课程!不要管学科,只要这门课每周甚至每天都要你写东西,你就去上。 你还可以动手写日记或者网志。你写得越多,写作就会变得越容易。写起来越容易,你就会写得越多。这是一个良性循环。 毕业前学好C语言 第二点我要讲的是C语言。请注意,我说的是C语言,而不是C++。虽然在实际使用中C语言已经越来越罕见,但是它仍然是当前程序员的共同语言。C语言让程序员互相沟通,更重要的是,它比你在大学中学到的“现代语言”(比如ML语言、Java语言、Python语言或者其它正在教授的流行垃圾语言)都更接近机器。你至少需要花一个学期来了解机器原理,否则你永远不可能在高级语言的层次写出高效的代码。你也永远无法开发编译器和操作系统,而它们恰恰属于目前程序员能够得到的最佳工作之列。别人也永远不会放心将大型项目的架构设计交给你。我不管你懂多少延续(continuation)、闭包(closure)、异常处理(exception handling),只要你不能解释为什么while (*s++ = *t++);这句代码的作用是复制字符串,或者不觉得这是世界上对你来说再自然不过的事情,那么你就是在盲目无知的情况下编程。在我看来,这就好像一个医生不懂得最基本的解剖学就在开处方,他看病的根据完全是因为那些娃娃脸的医药厂商销售代表说这种药有用。 毕业前学好微观经济学 如果你没有上过任何经济学课程,那么我首先来做一个超短的评论:经济学是这样的学科之一,刚开始学的时候轰轰烈烈,有许多有用的、言之有理的理论和可以在真实世界中得到证明的事实,等等;但是,再学下去就每况愈下,有用的东西就不多了。经济学一开始那个有用的部分正是微观经济学,它是商业领域所有重要理论的基础。跟在微观经济学后面的东西就不行了。你接下来学的是宏观经济学,如果你愿意,尽管跳过去,也不会有什么损失。宏观经济学开头的部分是利息理论,内容比方说是利率与失业之间的关系,但是怎么说呢,看上去这部分里面还没有被证实的东西多于已经被证实的东西。学完这部分,后面的内容越来越糟糕,许多经济学专业的学生实际上都变成在搞物理学,因为这样才能在华尔街上找到更好的工作。但是不管怎样,你一定要去学微观经济学,因为你必须搞懂供给和需求,你必须明白竞争优势,你必须理解什么是净现值(NPV),什么是贴现,什么是边际效用。只有这样,你才会懂得为什么生意是现在这种做法。 为什么计算机系的学生也应该学经济学?因为,从经营一家公司的角度来看,比起那些不懂的程序员,一个理解基本商业规则的程序员将会更有价值。就是这么简单。我无法告诉你有多少次我是那样地充满挫折感,因为我看到了太多的提出一些疯狂的想法的程序员,这些想法在代码上也许可行,但在资本主义世界中毫无意义。如果你懂得商业规则,你就是一个更有价值的程序员,你会因此得到回报的,但是前提是你要去学习微观经济学。 不要因为枯燥就不选修非计算机专业的课程。 想提高GPA绩点的一个好方法就是多选修非计算机系的课程。请千万不要低估你的GPA的重大意义。千千万万的人事经理和招聘人员在拿到一份简历的时候,第一眼就会去看GPA,包括我也是这样。我们不会为这种做法道歉。为什么?因为GPA不反映单个的成绩,而是代表了许多个教授在一段很长的时间中,在不同的情况下,对你的表现的一个总的评估。SAT成绩难道不够吗?哈,那只不过是一场几个小时的测试罢了。GPA中包括了四年大学期间你的小论文、期中考试和课堂表现,总数有几百次之多。当然,GPA也有自己的问题,不是百分之百准确。比如,这些年来,老师对学生的打分越来越宽松,学习成绩有通货膨胀的趋势。再比如,GPA无法反映课程的难度,没人能够看出你的GPA是来自无名社区大学家政系的轻松课程还是来自加州理工学院针对研究生的量子力学课程。渐渐地,我形成了一套自己的做法,首先我会过滤掉所有来自社区大学、GPA低于2.5的简历,然后我会要求剩下的人给我寄成绩单和推荐信。我再从中发现那些成绩一贯优秀的人,而不是那些仅仅在计算机系课程中得到高分的人。 为什么我要关心某人的“欧洲历史”课程成绩呢,毕竟作为雇主我要找的应该是程序员啊?何况,历史是那么枯燥,不得高分很正常。哦,这么说来,你的意思是我应该雇用你,而不用考虑一旦工作变得枯燥你会不会努力工作?别忘了,在编程工作中也有很枯燥的东西。每一项工作都有枯燥难耐的时刻。我不想雇用那些只想干有趣事情的人。 选修有大量编程实践的课程 我依然清楚记得我发誓绝不读研究生的那一刻。那是在一门叫做“动态逻辑”的课程上,教师是活力十足的耶鲁大学教授Lenore Zuck,她是计算机系那些聪明的老师中最聪明的人之一。 如今, 由于记忆力糟糕, 我已经差不多把这门课的内容忘光了,但是不管怎么说,在这里我还是想要对付着说一下。大致上,形式逻辑的意思是说,如果条件成立,你就能证明结论也成立。比如,根据形式逻辑,已知“只要成绩好,就能被雇用”,然后假定“Johnny的成绩好”,你就可以得到一个崭新的结论“Johnny会被雇用”。这完全是经典方法。但是,一个解构主义者(deconstructionist)只需要10秒钟就能破坏形式逻辑中所有有用的东西。这样一来,留给你的只是一些趣味性,而不是实用性。 现在再来说动态逻辑。它与形式逻辑其实是一回事,但是必须再多考虑时间因素。比如,“你打开灯之后,就能看见自己的鞋子”,已知“灯以前是亮的”,那么这就意味着“你看见了自己的鞋子”。 对于像Zuck教授那样聪明的理论家,动态逻辑充满了吸引力,因为它看上去很有希望让你在形式上证明一些计算机程序的相关理论问题。这样做说不定很有用。比如,你可以用它在形式上证明,火星漫游车的闪存卡不会发生溢出(overflow)问题,不会因而整天一遍又一遍地重启,耽误了它在那颗赤红色的星球上漫游寻找火星人马文(Marvin the Martian)。 在第一堂课上,Zuck博士写满了整整两面黑板,甚至黑板旁边的墙上都写上了很多证明步骤。需要证明的问题是,有一个控制灯泡的开关,现在灯泡没有亮,这时你打开了开关,请证明灯泡将会点亮。 整个证明过程复杂得不可思议,处处都是陷阱,必须十分小心。保证这个证明不出错太困难了,还不如直接相信打开开关灯就会亮。真的,虽然证明过程写满了许多块黑板,但是还是有许多中间步骤被省略了,因为如果要从形式逻辑上完整证明所有步骤,那就琐碎得无法形容了。许多步骤是用各种经典的逻辑证明方法推导得到的,包括归纳法、反证法等,甚至有些部分还是由旁听的研究生证明的。 留给我们的课后作业是证明逆命题:如果灯原来是关着的,现在却亮了,那么请证明开关的状态一定同原来相反。 我动手开始证明,我真的去证明了。 我在图书馆里待了很长时间。 我对照着Zuck博士的原始证明想依样画葫芦。研究了几个小时之后,我在其中发现了一个错误。可能我抄写的时候抄错了,但是这使得我想通了一件事。如果花费3个小时,写满了一块又一块的黑板,每一秒钟都可能出错,最后能够证明的却只是一个很琐碎的结论,那么这种方式有多大的实用性呢?在活生生、充满趣味的现实世界中,你永远都不会有机会使用它。 但是,动态逻辑的理论家们对这一点不感兴趣。他们看上它不是因为它有用,而是因为它可以为他们带来终身教职。 我放弃了这门课,并且发誓绝不会去读计算机科学的研究生。 这个故事告诉我们,计算机科学与软件开发不是一回事。如果你真的非常幸运,你的学校可能会开设很像样的软件开发课程。但是另一种可能是,你的学校根本不教你在现实中如何编程,因为精英学校都觉得,教授工作技能最好留给职业技术学校、犯人重返社会的培训项目去做。你到处都能学怎么写代码。别忘了,我们是耶鲁大学,我们的使命是培养未来的世界领袖。你交了16万美元的学费,却在学循环语句的写法,这怎么可以?你以为这是什么地方,难道是机场沿途的酒店里临时拼凑起来不靠谱的Java语言培训班?哼哼。 麻烦在于我们没有一种真正教授软件开发的专门学校。你如果想成为一个程序员,你可能只能选择计算机科学专业。这是一个不错的专业,但是它同软件开发不是一回事。在那些400等级的课程代号中,去寻找名称中带有“Practicum”这个词的课程吧(编者注:指供人实习的课程)。不要被这个拉丁语单词吓倒,这些都是有用的课程,之所以起这种名字,只是为了让那些文绉绉、装腔作势、满嘴胡说八道的公司经理们觉得高深莫测。 别担心所有工作都被印度人抢走 我首先要说的是,如果你本身就已经在印度了,或者你就是印度人,那么你真的毫无必要去想这件事,根本不用琢磨所有的工作机会是不是都跑到了印度。那些都是非常好的工作,好好地享受吧,祝你身体健康。 但是,我不断听说计算机系的入学人数下降得很厉害,已经到了危险的程度。根据我听到的说法,其中的一个原因是“学生们不愿去学一个工作机会都流向印度的专业”。这种担心大错特错,有很多理由可以反驳。首先,根据一时性的商业潮流决定个人的职业选择,这是愚蠢的。其次,即使编程工作无一幸存地都流向了印度和中国,但是学习编程本身依然是一种第一流的素质训练,可以为各种超级有趣的工作打下基础,比如业务流程工程(business process engineering)。再次,不管是在美国还是在印度,真正优秀的程序员依然是非常非常短缺的,这一点请相信我。不错,确实有相当一批失业的IT从业者在那里鼓噪,抱怨他们长时间找不到工作,但是你知道吗?即使冒着触怒这些人的风险,我还是要说,真正优秀的程序员根本不会失业。最后,你还能找到更好的专业吗?你觉得什么专业好?主修历史学?如果那样,你毕业的时候就会发现,根本没有其他选择,只能去法学院。不过我倒是知道一件事:99%的律师都痛恨他们的工作,痛恨他们当律师的每一分钟。可是,律师每周的工作时间偏偏长达90小时。就像我前面说过的:如果你喜欢编程,那么你真是受到了上天的眷顾。你是非常幸运的少数人之一,能够以自己喜欢的事谋生。 不过说实话,我不觉得学生们真的有上面的想法。近年来,计算机系入学人数的下降只是回到了历史上的正常水平,因为前些年的互联网狂热使得入学人数出现了大泡沫,抬高了基数。由于这种泡沫,许多并不真的喜欢编程的人也来读计算机系。他们心里想的是,只要进了计算机系,将来就能找到诱人的高薪工作,就能获得24岁当上CEO、进行IPO的机会。谢天谢地,这些人现在都离计算机系远远的了。 找一份好的暑期实习工作 精明的招聘负责人都知道,喜欢编程的人高中时就将牙医的信息输入了数据库,进入大学前就去过三次电脑夏令营,为校报做过内容管理系统,有过软件公司的夏季实习经历。招聘负责人就是要在你的简历上找这些东西。 如果你喜欢编程, 就不要随便什么工作都答应,否则你会犯下最大的错误。不管是暑期工作,还是兼职或者其他性质的工作,只要与编程无关,就不要轻易接受。我知道,其他19岁的孩子都想去购物中心里打工,在那里折叠衬衫。但是你与他们不同,你19岁时就已经掌握了一门非常有价值的技能。将时间浪费在折叠衬衫上是很愚蠢的,等到毕业的时候,你的简历上本应该写满了一大堆与编程相关的经历。就让那些财经类的毕业生去租车公司“帮助人们满足他们租车的需要”吧,你要干的是别的事(在电视中扮演超人的Tom Welling注1除外)。 为了让你的生活变得更容易一些,也为了强调这整篇文章完全是为了满足我的个人目的,我要告诉你,我的公司——Fog Creek软件公司——提供软件开发方面的暑期实习机会。我们非常看重简历。“比起其他公司的实习工作,你在Fog Creek最有可能学到更多的编写代码、软件开发、商业运作方面的知识。”这是去年夏天我们的一个实习生Ben说的。他会这样说,并不完全是因为我派了人到他的宿舍让他这样说。我们接受实习申请的截止日期是2月1日。一起来吧。 如果你听从了我的建议,你还是有可能落得一个悲惨的下场,比如很早就卖掉了微软公司的股票,再比如拒绝了谷歌公司的工作机会,原因是你想要一间自己的可以关上门的独立办公室,或者做出了其他生命中愚蠢的决定。但是,这些可不是我的错。我一开始就告诉过你,不要听我的话。 (注1 : T o m W e l l i n g是一个美国演员, 在电视剧《超人前传》(Smallville)中扮演超人。该电视剧讲述还没有成长为后来超人的克拉克·肯特少年时代的故事。) 作者简介: Joel Spolsky,世界最具影响的程序员网志Joel on Software的主人,软件业一位旗帜鲜明的思想者,一位传统软件管理理念的挑战者。他创办的这个网站被程序员誉为“反呆伯特宣言书”,并被翻译为三十多种语言。Joel毕业于耶鲁大学,随后即进入微软公司工作,曾任微软公司E x c e l 开发小组项目经理。现在他在自己创办的Fog Creek软件公司任CEO。此外,他与人合办的Stack Overflow已经成为如今最热门的技术网站。
posted @ 2010-01-28 21:48 chaosuper 阅读(102) | 评论 (0)编辑 收藏

link: http://www.cnblogs.com/tomin/archive/2008/11/18/1335730.html
如果你已经有较多的面向对象开发经验,跳过以下这两步:   第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET。 ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去!   第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习.NET Framework。ASP.NET是建构在.NET Framework之上的技术,你对.NET Framework了解得越深,学习ASP.NET就越快。 举个例子:下面简单列出几个对掌握ASP.NET非常重要的概念: 对象的内存模型,委托,事件,多线程,程序集和应用程序域,安全模型 .NET Framework当然还有许多其它的东西,但不理解与把握清楚上述这些东西,是很难真正把握ASP.NET的。 出于急迫的心情与现实的考虑,不少人没有扎实的面向对象基础就想直接学习ASP.NET,其结果只能是欲速则不达。 在具备了OO基础之后,以下是具体的学习ASP.NET技术步骤。   第一步:学习HTML与CSS   这并不需要去学一大堆的诸如Dreamweaver,Firework之类的各种网页设计工具,关键是理解HTML网页嵌套的block结构与CSS的box模型。许多ASP.NET控件最后都必须转化为HTML。而且,div+CSS是当前主流的网页布局模型。 学习这部分时,关键在于理解概念,而不需要将精力花在美化页面的许多技巧上,那是网站美工的工作,不是程序员的工作。   第二步:学习JavaScript   JavaScript不是Java,它主要运行于浏览器端。可以完成许多工作,功能也很强大:比如它将客户端网页中的HTML元素看成一棵树,可以编写代码访问并修改树节点,动态生成新的HTML代码,从而达到动态修改网页显示特性的目的。   JavaScript在目前的网站开发中用得很多,非常重要。   另外,它也是目前非常流行的AJAX技术的基础。   第三步:学习计算机网络原理   找一本大学<计算机网络>教材,重点看看它的有关互联网的部分,了解一些域名解析和HTTP协议等知识。这是进行互联网开发的理论基础。   第四步:学习ASP.NET表示层技术,会设计Web页面   需要结合先前打好的面向对象技术的基础,至少掌握以下内容:   (1) 各种Web控件的使用方法,   (2) 理解信息在网页中的传送方式,比如Cookie,ViewState,Session等的使用。   (3) ASP.NET应用程序与网页的生命周期,以及相关对象(比如httpcontext,response,request)的用途。   (4) ASP.NET实现事件驱动的内幕   (5) 自定义用户控件   再次强调一下,没有OO基础,很难掌握上述技术,就只能被这些东东牵着鼻子走了,会很被动。   第五步 掌握数据库技术   具体地说,要学习以下内容:   (1) 学会使用SQL Server 2005:不要求精通它的各种工具与管理配置技术,但至少知道如何连接,如何建表,如何创建存储过程   (2) 学习ADO.NET,掌握使用代码人工访问数据库(别用VS2005的向导)的方法   (3) 学习数据绑定控件的使用   第六步 理解多层架构   这时,先前在OO学习阶段涉及到的程序集与应用程序域等就派上用场了,现在,网站架构大多采用多层架构:表示层、业务逻辑层、数据存取层以及数据库本身。   可以先上网找一此多层架构的资料看,再找一个现成的比较复杂的开源ASP.NET项目分析一下其架构就差不多了。基本上都是一个套路,到处应用。   有的朋友问:学习架构是不是必须学习设计模式。   我的看法是:不必!当然,你如果学习过设计模式,那当然更好。但在实际开发中,如果只想着机械地套用某种模式,反而起不到好的结果。我的观点:在学习设计模式时要多思多悟,其思想就会渐渐地融入你的大脑,在真实的设计实践中,忘掉所有的写在书上的模式,一切从实际出发,相信你的直觉,只要达到设计要求的方案就是可行的方案,事实上,你这样做了之后,回过头来再看,会发现你的设计往往暗合设计模式的理论。   第七步 学习XML与Web Service   先了解XML的基础知识,找本讲XML的书看一下就差不多了,然后,再学习Web Service。Web Service其实可类比为远程方法调用(以XML格式表达的调用信息)。   学 到了这里,如果你还有兴趣,不妨再去看看SOA,不过SOA的资料都是理论与概念,看起来比较郁闷,而且离实际开发可能比较远。所以,这是可选项。   第八步 学习AJAX   学习AJAX的主要目的是创建具有更丰富特性的Web表示层,而经过前面七步的学习,到此再学习AJAX已水到渠成,所有的基础都已具备,不会有太大的问题了。   在基础未具备的前提下直接学AJAX,就象“浮沙之上筑高台”,所以,将AJAX的学习次序安排在这里。   第九步 学习RIA技术   RIA:Rich internet application,可看成是将C/S与B/S优点合二为一的尝试。就具体技术来说,主要指微软的Silverlight(WPF_E),毕竟前头一路行来都是微软路线。   不过目前学习它主要是为了技术储备。估计此技术的普及需要2到3年的时间,因为预装Vista的机器今年才开始大卖。
posted @ 2010-01-26 16:53 chaosuper 阅读(111) | 评论 (0)编辑 收藏

Editor bluefish vi/vim/gvim gedit kate Compiler gcc/g++ Debugger gdb
http://blog.chinaunix.net/u3/94284/article.html
posted @ 2010-01-26 15:42 chaosuper 阅读(111) | 评论 (0)编辑 收藏

珍惜大好时间 努力 积极主动的学习新的知识 提高实际的能力和知识积累 http://blog.csdn.net/metasearch/category/368809.aspx
posted @ 2010-01-26 11:10 chaosuper 阅读(71) | 评论 (0)编辑 收藏

仅列出标题
共12页: 1 2 3 4 5 6 7 8 9 Last