百度贴吧10亿量级LAMP架构分享

贴吧是功能性产品,唯快不破是永恒的准则,这一特点决定了快速迭代是需要解决的关键性问题。快速迭代,分解开来有如下部分:开发阶段,快速开发;测试阶段,包含了环境快速搭建、自动化测试工具;运维阶段,包含了集群管理技术、自动化运维工具;同时,这三方面的工作需要一个整体性的解决方案衔接起来。

早期的贴吧,作为一个高性能社区,功能相对单一,全部采用C语言开发,系统可重用程度低,开发、测试效率低,运维方面的积累也很少。为了提高效率,开始尝试 LAMP 架构,经过几年的发展,贴吧已全部迁移到了 LAMP。随着产品规模急剧膨胀,30+ 子系统,150+ 模块,500+ 机器,10亿+流量,在 LAMP 架构方面积累了很多经验,逐渐形成了快速迭代的一体化方案。如下图所示:

该解决方案由开发阶段、测试阶段、运维阶段组成。开发阶段又分成接入层、业务逻辑层、存储层。该解决方案支撑大规模的线上应用,同时保持了快速迭代的特性。基于该解决方案,开发人员能专注于业务逻辑开发,测试人员能专注于持续集成,运维成本能大大降低。

开发

开发方面分为接入层、业务逻辑层、存储层。

接入层处于浏览器和后端服务之间,用来解析 http 协议并组织成相应的协议格式,完成客户端和服务器之间的通信,还包括攻击防范、页面缓存、负载均衡等多种功能。Web Server 是其核心组成部分。接入层的目标是通过统一的方案提供简单可依赖的接入层架构,经过全面调研 nginx 具有通用性强、效率高、功能全面、配置灵活等特点,是 webserver 未来发展的主力军,确定采用 nginx 统一接入层。

业务逻辑层包含了 PHP 框架、业务逻辑、LIB 库、交互层。业务逻辑层常常包含一些开发规范,这些规范就像法律一样,我们不仅要有法可依,还要有法必依。在我们的解决方案中,PHP 框架=规范+库,规范比如目录部署规范、URL 规范、配置规范等,这些规范通过相应的库实现,以达到有法必依的目的。

LIB 库封装常用的功能。基于这个解决方案,开发者开发应用,只需完成业务逻辑部分。

中间层,如下图所示,包含在业务逻辑层中,对于业务逻辑层的快速迭代非常重要。中间层对下做交互抽象,支持各种协议屏蔽协议细节;通过资源定位屏蔽部署细节;通过负载均衡提高系统稳定性。中间层对上做接口抽象,支持服务整合、接口适配、公共逻辑。

中间层首先建立系统–子系统–模块的体系,进行服务整合,图中的 API-LIB 就是根据子系统划分,将各模块的接口(MIDL: Module IDL)转化为子系统接口(SIDL: Service IDL);接口适配,SERVICE 的接口通过 SIDL 描述,让接口描述、接口文档、线上代码等自动同步,可维护性大大提高,同时通过元数据规范保证全系统的接口一致,易用性大大提高;收敛公共逻辑,对于公共逻辑,比如权限逻辑,收敛起来可维护性大大提高。

存储层,提供各种通用服务、组件。其中的通用数据存储框架提供通用的数据存储和访问解决方案,以一种统一的设计模式来支持大多数数据存储模块的设计和实现;统一数据访问接口,对外部屏蔽数据拆分和存储的细节;做到数据存储的良好扩展性,通过通用的数据拆分模式来应对数据增长;将具有共性的需求抽象成通用服务或通用库,以简化设计和开发。

基于该解决方案,开发一个应用只需要:在接入层配置相应的分流,在业务逻辑层开发业务逻辑,使用存储层合适的服务或基于框架完成数据模块开发。能大大的提高开发效率,支持快速迭代。

测试

测试方面,为了支持快速迭代,必须提高自动化程度。而影响自动化的首要因素就是环境自动构建,常见的问题有:环境复杂,比如关联关系复杂;环境搭建代价过大;环境功能不完整等。采用基准环境能解决这一问题,项目上线后自动从 scmpf 更新到基准环境;测试环境/开发环境从基准环境同步。基于基准环境,系统级别的持续集成也成为可能,同时可以集中大量测试工具。

运维

运维方面面临着很多问题:服务迁移成本高,环境不一致带来各种回滚,机器利用率不均衡,运维自动化程度低。为了解决这些问题,提出 PHP 系统运维方案。环境同步方面,主要是代码同步的问题,采用运维规范+监控的方案;性能监控方面,基于交互层完成请求状态、交互性能监控,基于调度中心获取机器状态;机器调度方面,通过调度中心完成动态/半自动机器调度。如下图所示:

展望

通过该 LAMP 解决方案,在开发、测试、运维方面都能极大的提高效率。未来在 LAMP 架构方面,需要更多的在规范化、平台化上下功夫。规范之后才能开展这种自动化的工作提高效率;平台化可以把各种规范固化下来,提供自动化的支持。

转自:http://news.cnblogs.com/n/123873/

1 热度 全文链接

11 Things every Software Developer should be doing in 2012.

Introduction

2011 is winding down and 2012 is upon us. Have you set any goals for 2012 both professionally/personally? Regardless of the answer, I’m sure one or two of the items listed below can help. I usually don’t blog many opinion posts, due to the fact that I like to keep my blog technical. This post is an exception. :)

11 Things every Software Developer should be doing in 2012.
  1. Get on Twitter– If you’re not using Twitter and are a Software Developer then you are missing out. I believe that Twitter is the one of the MOSTimportant tool a Software Developer can use. Why?

    1. Regardless if you have 10 followers or 10000 followers, any coding question can be found and answered in a matter of seconds using Twitter Hashtags.

    2. Get software developer news straight from the source by following other developers.

    3. Again hashtags – To monitor topics important to you. For example, I use it to monitor #wp7, #silverlight and #wpf.

    4. To stay engaged in a conversation with other developers and to see what projects they are working on.

  2. Read StackOverflowDaily– StackOverflow is the number one forum for asking a coding question. Even if you don’t have an account, it’s worth it just for browsing questions and learning. I think it is a wise investment of your time to spend at least 20 minutes a day reading StackOverflow.

  3. Start a Blog– I believe that everyDeveloper should have a blog. Why?

    1. It is a footprint that we leave for other developers studying our craft.

    2. It allows you to become engaged in the community.

    3. It helps you market yourself as a professional.

  4. Get out there –Get out of your shell and start talking to other developers at local user groups/other meet ups/conferences. I will let you in on a secret – most everyone is shy at first. If you start a conversation with them then it usually takes off very fast.

    1. Networking with other developers is big – really big. You start building connections in the industry and if you ever need help then you have someone to go to.

  5. Carry around a modern phone - If you’re a developer and carrying around an older phone then its time to upgrade. I remember a manager at one of my jobs that had to walk back to his desk to email me something. I remember thinking, “This guy is in IT?” Just like some industries you need to drive a fancy car, have nice clothes or the latest jewelry. In technology, we need to stay current with our computers, software and mobile phones.

  6. Embrace Mobile – Do you think this “mobile” thing is going away? Well, it is just getting started. You need to know more than how to develop for the iPhone, WP7 or Android. You need to learn how to create web applications that will run on everymobile device. (Including phones, iPads, Windows and Android slates). I believe that every developer will have to create a mobile application in his/her programming career. This is something a modern developer cannot ignore.

  7. Learn at least one design pattern- I am not going to tell you which one you should learn or focus on, but you need at least one. I prefer MVVM for myself because I am a Silverlight/WPF/WP7 Developer. If you are familiar with at least one design pattern then it would make me feel better about hiring you.

    1. I’d start with this book: Gang of Four – Design Patterns: Elements of Reusable OOS.

  8. Set reachablegoals each and every year – Create a short-list of goals that you are looking to accomplish in the next year. Not only should you be challenging yourself with a set of goals, you should also create a quarterly outlook/Gmail reminderto evaluate your progress. I am a believer that you should start smallwith a goal and build up from there. I did this with my MCPD certification. I shot for the MCP, then MCTS then the MCPD.

  9. Learn a different programming language – Simply put, it broadens your perspective and permits a deeper understanding of how a computer and programming languages actually work.

    1. If the only tool you have is a hammer, you'll treat every problem as a nail.

  10. Boost your confidence – It always amazes me how few developers are confident in themselves. If you feel like you’re behind on something then learn it. I can’t find any excuse for staying ignorant in this industry. There is just too many FREE resources on the web.

  11. Read Blogs/Programming Books/Magazine – How many programming books have you read this year? What about good developer magazines? I believe a good developer would read at least 5 programming books a year and at least a magazine or two monthly. Even if you don’t have a subscription to MSDN you can get the .PDF for free a month after release. How can you get better if your not constantly reading?

转载自:http://michaelcrump.net/11-things-every-software-developer-should-be-doing-in-2012

标签:

全文链接

Yellow (Originally Performed By Coldplay)--Scala & Kolacny Brothers

Hello world !

第一篇博客Hello world !

以前的wp博客的正在搬家中!

点点的博客能绑定独立域名真不错!

感谢 @夜末 给我搭建php环境帮我导出以前的wp博客里文章!

1 热度 全文链接

没事儿别优化!

本文是从 Don’t optimize! 这篇文章翻译而来。

事实上你应该优化,但要在正确的地方,有足够的理由。我待会儿再聊这个。

我最近和在 Badgerpunch Games 的几位朋友一起发布了一个小的 以XNA为基础的游戏,而且通过论坛和Twitter与这个独立的游戏开发组织保持密切的联系。游戏开发者十分在意性能问题,而且这很必要。没有人想要一个运行不畅的游戏。因为这些对性能的担忧,出现了很多关于优化技巧的提示和论文,都围绕着如何能实际有效的缓解性能问题。大多数的技巧提示和文章都提供了有价值的信息、有相应的用处,但你会发现很少有文章能触碰到性能优化上的主要问题:什么时候不该优化,为什么。

优化就是这样的事:你的程序可以一直优化下去,但工时上的开销和取得的效果的对比会很快让你陷入困境。我记起了九十年代早期在 Amiga Demo 公司的一幕。我大概花了半年的时间去优化那个3D旋转的汇编程序片段。最终我觉得该优化的几乎都优化了。起初几周我努力减少CPU的指令循环,获得了惊人的减幅!但随后的数月里,我几乎没法再进一步的压缩,最终只得放弃…我这段程序超级的快,可是,其他程序员的3D图形跑的比我还要快,我无法理解,这怎么可能?

直到数年后我在大学里学了矩阵后我才明白其中的奥秘。我的程序里每个3D坐标用9次乘法,这是一个没有优化的矩阵算法,它可以被压缩成6次乘和两个加法,这样每个坐标点可以节省数百次的CPU指令循环…太郁闷了!

这个故事的寓意?你可以优化你的程序,让它像星星一样闪亮,但如果有人有更好的算法,让同样的程序跑的更快,你还是很失败。

你很失败吗?只是在有意义的时候才能这样说。在上面的性能优化的故事里,3D旋转效果是被限制在一个16位的机器上的,这种情况下最快的程序证明了最出色的程序员,这时它的意义就很大了。 

这让我们回到了最初的那个问题。不要优化——如果优化是无关紧要的。重要的是让你的代码简单易懂,容易修改!当你的程序具有这三个特征时,它是否被优化已经无关紧要了。

如果程序太慢,使用一个分析工具,找到什么地方需要优化。有时你并不需要一个分析工具,你只需要根据你的实际数据进行优化。当你找到了问题的区域,尽可能的用最简单的方式修改它们,看看修改后有什么效果。最终让你的程序达到到可以接受的性能程度。如果还不行,你需要根据你的代码做算法上的修改。这就是为什么要保持代码简洁、易于修改的原因了。

让代码保持简单易读、易于修改的主要原因是为了寻找bug,这是一个阅读和修改代码的过程。程序越易懂,问题越容易修改。这是毫无疑问的…可是仍然有人坚持把事情能的尽可能的复杂,只是为了满足个人的野心!我曾经看到一段Java代码里有多层递归调用的if语句。这是一个最糟糕的无意识里做出的损毁程序的事。必然的,到处都是bug …看的我想哭。

另外一个保持代码简洁的原因是以最简单的方式告诉编译器你的程序的意图。编译器对简单的代码有更好的优化能力。如果你是一个虚拟机上使用JIT编译器,这更显的重要。虚拟机和按需编译可以使你的程序能在不同的VM版本上运行。基本上虚拟机版本越新,你的代码越简单,当程序运行时,你就能获得更好的优化结果。

早期版本的Java虚拟机做很少的编译优化,所以像for循环、反向计数等技巧可以节省一些循环。但是最新版的编译器和按需优化处理针对最常见的for循环形式进行了优化。性能问题从代码转移到了虚拟机上,长时间运行的程序在代码上的优化技巧不再具有很重的份量。

所有的论述浓缩成这个:除非你知道优化什么,否则别去优化。这并不是说你不需要去考虑性能问题。你始终应该把性能问题放在心上。它有可能是你算法选择上的问题,设计、实现上的问题,但你的主要精力应该放在保持代码简洁易读,易于修改上。

转载自: 外刊IT评论

提高编程技能最有效的方法

StackExchange.com上有两个贴子( 贴子一贴子二),贴子名叫“What is the single most effective thing you did to improve your programming skills?”–对你的编程技术提高最有效的一件事是什么?回复的人中给了很多很不错的建议,我把他们总结了一下,十条,相信一定会对你有用。(注意:顺序是我自己按我的个人经验排的)

  • 和比自己聪明的能力比自己强的人工作。学习他们的代码,他们的做事方法,看一看那些人是怎么处理错误的。



  • 总是倾听别人怎么说,无论那个的资历和职位是什么样的。



  • 实践,实践,实践,总是不满意于一开始出来的事。



  • 多问问自己,现在在写什么代码?为什么要这样写成这样?还有没有更好的方法?



  • 学习多样的技术,多多比较它们,并一定要了解各种技术的优缺点。



  • 总是问别人好的问题。



  • 多回头看看走过的路,做过的事,写过的程序,感觉一下它们有多烂。



  • 多读读那些大师写的书。



  • 不要总坐在电脑前编程序,多做做运动,多到户外走走,和非技术人多接触,向他们学习。


除了这些,下面是我个人想给你的建议——

可能只能算精神,不能算方法。我以前也写过一篇《 五个方法成为更好的程序员》,《 十条不错的编程观点》,还有《 优秀程序员的十个习惯》这几篇文章也能给你一些启发。

  • 热情。对编程充满热情。这种热情会导致强烈地专研精神,和努力的精神。专研精神相当重要,它是畏难情绪的天敌



  • 知道。学习技术要“知其道,明其理”,而不仅仅只是了解知识。举例,为什么C++有“初始化列表”而Java却没有?为什么Java的没有多重继承?为会有了TCP还要UDP?对于一个事物,什么是好的,什么是不好的。不但要了解其表面,还要了解其思想。只有了解原始的初衷和目的,你才能真正“知道”



  • 犯错。不犯错误永远没有经验,从自己的错误和别人的错误中学习,只有自己犯了错,才会真正明白。犯错不可怕,可怕的是不会总结只有真正的摸爬滚打过的人才是强人。技能和经验总是用错误去换来的



  • 回顾。要多去回顾过去,看看历史上发生过的事。这样你才能明白事物的发展规律,从面才能了解未来的路。举例:单机 -> Client/Server -> 中间应用层 -> 多层结构 -> 分布式结构。 C -> C++ -> Java,等等,等等。未来其实就在回顾过去之中



  • 质疑。质疑精神很重要。质疑通常会导致不同意见甚至反对意见。也许你会质疑错,也许你会被质疑,但是你的认知也会因为不同的观点而变得完整。有所同有所不同(“同”为同意及相同),观点因为不同才能迸发出火花,事物也此而发展,世界因为不同而精彩


转载自: coolshell.cn

作为一个程序员,数学对你到底有多重要

每个计算机系毕业的人,大都学过不少数学课,而且不少学校的计算机系的数学课,通常比一般的其他工科专业的数学要难一些,比如不上高等数学,而是学数学分析,不上线性代数而去上高等代数。但是,大部分毕业了后去做程序员的人,即使是所谓的名校计算机系毕业的,大都工作中也基本完全用不上学的那些数学,基本上,一半时间在CRUD,另一半时间在处理各类字符串、链表、Hash表,知道在面试中回答各种排序的时间复杂度是他们需要的数学的上线了。

而在念书的时候,虽然上大学之前,有不少内行的外行的,年老的年轻的人告诉你,数学很重要啊。但是,通常来说,各个学校的计算机系的同学么,爱好学习的,可能重视的也是Thinking in Java,C++ Primer之类的语言书,或者设计模式之类的架构书,抑或是算法与数据结构这些玩意儿;而像我这样天天偷懒放羊的,也不会把数学当作是什么重要的课程好好学习。所以,“数学真重要”,这句话,似乎对于大家来说,始终只是飘在天上的一句话,随风飘逝了。

于是,五年过去了,程序员们都有了不少的工作经验了,如果不是对工作毫无追求混吃等死的程序员的话,对于天天干活的语言,不论是Java还是C++应该都熟能生巧了,所谓的设计模式、重构、自动化测试等等也手到擒来了,大部分人的title上都加上了Senior了,牛一点的后面大概还跟上了一个Manager,然而,大家都开始考虑一个新的问题——“30岁以后怎么半?”,于是,转PM的转PM,考公务员的考公务员,像我这样仍然抱定——“你看人家美国Rohit都50了还不是天天写程序,别人想请还请不到的”的单纯想法的人越来越少了。然后,就算这些人,时不时也会觉得,自己天天干的超越CRUD的,所谓写点OO的框架,不也是很无聊的体力活么,写程序的人干两年谁都会干。于是,又有不少人下海创业了,多年以后,这些人中的大部分都会和我一样悲催的没有挣到前继续回来给大大小小的公司写程序。

其实,杯具往往发生在一开始,其实,要是咱们当年好好学习,才会发现,也许数学对于你当个不错的程序员来说,没那么重要,但是要再往上走一步,有一点点技术上的创新,就都是数学的事儿了。两年前,我在T公司,用Configurator处理某个程序的时候,开始有点儿意识到这一点了,于是,那阵子还花了不少时间重新翻了翻数理逻辑。今年,换了新工作后为了工作看点儿机器学习的东西的时候,终于发现,这全都是数学啊。当你要超越CRUD,做任何一点点有创新性的技术的时候(不说产品),最有机会遇到的问题,其实是数学问题。虽然从Spring到Hibernate到Rails之类的框架,或者Hadoop,HBase之类的分布式计算框架,也都是技术上的重大革新,但是这些框架类的程序,完善都是阶段性的,一旦出现后,很快都会有相应的Best Practice,又会成为熟练工种的活。而真正针对问题域的解答,反是每天都可以有些新鲜的想法、思路和方案的,这些,往往有个数学的门槛。所以如果你真是挺喜欢写程序的,而且希望自己一直能写更好玩更难的程序,总有一天,你要过了这一道坎儿。

所以我很是同意不知道是谁说得,如果你只想当个good programmer,那么数学不重要。但是如果你想当个great programmer,那么数学很重要。在你手里只有锤子的时候,你看什么东西都会是个钉子,想想你如果没有学过算法和数据结构,可能你的大部分程序需要自己写排序的话,都会是傻傻地冒泡吧,反正对于大部分程序来说,在现在这么快的PC下,这点时间差别,大部分情况下,也就是让你等程序执行测试的时候,多个倒杯水的时间。但是很多新鲜,好玩,有挑战的问题,很多数学的概念没有的话,恐怕不是多等个倒水的时间了。而如果你过了这个门槛,你又会发现,一个崭新的世界,又到了你的面前。

回过头来,我说数学重要的话,那么重要的是哪些呢?大家常说的通常是离散数学,不过最近比较热门的机器学习这个方向,我目前看到的相关资料都大量依赖于线性代数和概率论,以及一点点微积分。所以,如果你和我一样,希望做点有追求的技术工作的话,开始花点时间学习数学吧。其实万事开头难,也许你和我一样,对着一堆公式符号,感到头晕眼花,但是如果真得按下心来,看上一个小时,这么坚持个一周,其实就会发现,这没啥难的,就当学门新的编程语言得了。

PS:如果在google中搜索“程序员数学”的话,第一个链接是 程序员怎样学数学博客园知识库高清版),我觉得这篇文章写得相当不错。我也非常同意,广度有限比较有效,容易激发学习的兴趣,而且能和实际的工作和现实世界的问题、项目相结合。

转载自: http://www.xuwenhao.com/2011/02/01/how-import-is-math-for-a-programmer/

深入详解DataTable

前言:ADO.NET概述

在学习DataTable知识之前,我们有必要了解下ADO.NET。以下摘自MSDN:

ADO.NET 对 Microsoft SQL Server 和 XML 等数据源以及通过 OLE DB 和 XML 公开的数据源提供一致的访问。数据共享使用者应用程序可以使用 ADO.NET 来连接到这些数据源,并检索、处理和更新所包含的数据。
ADO.NET 通过数据处理将数据访问分解为多个可以单独使用或一前一后使用的不连续组件。ADO.NET 包含用于连接到数据库、执行命令和检索结果的 .NET Framework 数据提供程序。您可以直接处理检索到的结果,或将其放入 ADO.NET DataSet 对象,以便与来自多个源的数据或在层之间进行远程处理的数据组合在一起,以特殊方式向用户公开。ADO.NET DataSet 对象也可以独立于 .NET Framework 数据提供程序使用,以管理应用程序本地的数据或源自 XML 的数据。
ADO.NET 类在 System.Data.dll 中,并且与 System.Xml.dll 中的 XML 类集成。当编译使用 System.Data 命名空间的代码时,请引用 System.Data.dll 和 System.Xml.dll。有关连接到数据库、从数据库中检索数据并在命令提示中显示该数据的 ADO.NET 应用程序示例,请参见 ADO.NET 示例应用程序。
ADO.NET 向编写托管代码的开发人员提供了类似于 ActiveX 数据对象 (ADO) 为本机组件对象模块 (COM) 开发人员提供的功能。

ADO.NET中包含的对象及其关系如下图:

 



1、DataTable简介

1.1 DataTable的定义

表示内存中数据的一个表。 我们知道数据库中存储的是实体表,实体表中有一系列的数据。而DataTable即存储在内存中的表,在持久化到数据库之前,是不会对数据库产生影响的,持久化到数据库可以使用dataAdapter.Update的方法(dataAdapter是某个实例化的DataAdapter对象)。

注意:当访问 DataTable 对象时,请注意它们是按条件区分大小写的。例如,如果一个 DataTable 被命名为“mydatatable”,另一个被命名为“Mydatatable”,则用于搜索其中一个表的字符串被认为是区分大小写的。但是,如果“mydatatable”存在而“Mydatatable”不存在,则认为该搜索字符串不区分大小写。
1.2 得到DataTable

得到DataTable有许多方法,下面简单罗列出来:

1.2.1通过构造函数得到DataTable 
DataTable() 不带参数初始化DataTable 类的新实例。
DataTable(string tableName) 用指定的表名初始化DataTable 类的新实例。
DataTable(string tableName, string tableNamespace) 用指定的表名和命名空间初始化DataTable 类的新实例。

1.2.2通过DataSet获取DataTable

DataTable dt=ds.Tables["TableName"];//TableName是表名

1.2.3 通过DataRow自定义DataTable的结构
DataTable dt= new DataTable("TB_USER");
DataColumn colUserID = new DataColumn("USER_ID", Type.GetType("System.Int"));
dt.Columns.Add(colCurrency);
DataColumn colUserName= new DataColumn("USER_NAME", Type.GetType("System.String"));
dt.Columns.Add(colUserName);
这样得到是一个表的结构,里面没有任何数据,表面为TB_USER。
1.2.4通过已有的DataTable得到新的DataTable
可以使用DataTable.Clone()方法获得现有DataTable的表的结构,这在实际中也是常用的
1.2.5通过DataAdapter填充DataTable
DataAdapter.Fill(dt);来填充DataTable,这也是新手常用的方法,通常是些sql语句,然后使用command,是最基础的方法。
1.2.6通过DataRow数组导入DataTable
DataRow [] drs;//drs是某个有数据的DataRow数组


foreach(DataRow dr in drs)

{

dt.ImportRow(dr);

}

1.3  DataTable常用属性


CaseSensitive 指示表中的字符串比较是否区分大小写。

ChildRelations 获取此DataTable 的子关系的集合。

Columns 获取属于该表的列的集合。

Constraints 获取由该表维护的约束的集合。

DefaultView 获取可能包括筛选视图或游标位置的表的自定义视图。

HasErrors 获取一个值,该值指示该表所属的

DataSet 的任何表的任何行中是否有错误。

MinimumCapacity 获取或设置该表最初的起始大小。该表中行的最初起始大小。默认值为 50。

Rows 获取属于该表的行的集合。

TableName 获取或设置DataTable 的名称。

1.4 DataTable是 ADO.NET中的重要成员

DataSet中可包括多个 DataTable,可将多个查询结构存到一个DataSet中,方便操作,而DataTable中又包括多个DataRow、DataColumn,可通过这些DataRow、DataColumn来查看、操作其中的数据,而需将操作结果返回给数据库的话,则可以调用DataAdapter的 Update方法。


 

2、DataTable成员之DataRow

DataTable是由一个个DataRow组合而成,DataTable.Rows[i]即表示其中的第i行。

DataRow有一个十分重要的状态(RowState),这个状态经常被我们忽略,从而导致一些莫名其妙的bug。RowState 的值是一个枚举类型的,RowState 有 Added, Modified, Unchanged, Deleted, Detached 几种, 分别表示 DataRow 被添加, 修改, 无变化, 删除, 从表中脱离. 在调用一些方法或者进行某些操作之后, 这些状态可以相互转化。我们不做什么判断就开始操作DataRow,这就有可能导致某些状态为Deleted的行也同时被操作,这样就有可能导致脏数据的产生。



























RowState 值说明Unchanged自上次调用 AcceptChanges 之后,或自 DataAdapter.Fill 创建了行之后,未做出过任何更改。Added已将行添加到表中,但尚未调用 AcceptChanges。Modified已更改了行的某个元素。Deleted已将该行从表中删除,并且尚未调用 AcceptChanges。Detached该行不属于任何 DataRowCollection。新建行的 RowState 设置为 Detached。通过调用 Add 方法将新的 DataRow 添加到 DataRowCollection 之后,RowState 属性的值设置为 Added。

对于已经使用 Remove 方法(或是在使用 Delete 方法之后使用了 AcceptChanges 方法)从 DataRowCollection 中移除的行,也设置为 Detached。
 

3、DataTable成员之DataColumn

 DataColumn 表示 DataTable 中列的架构。

3.1 DataColumn中常见的熟悉及其说明如下:























































属性名说明Unique设置DataColumn对象是否不允许重复的数据Table DataColumn对象所属的DataTable对象ReadOnlyDataColumn对象是否只读Ordinal字段集合中的DataColumn对象顺序DefaultValue  DataColumn对象的默认值DataTypeDataColumn对象数据类型ColumnNameDataColumns集合对象中的字段名称Count DataTable对象中的字段数CaptionDataColumn对象的标题AutoIncrement加入DataRow时,是否自动增加字段AutoIncrementSeedDataColumn对象的递增种子AllowDBNullDataColumn对象是否接受Null值
 

3.2 DataColumn.Expression 表达式

获取或设置表达式,用于筛选行、计算列中的值或创建聚合列。表达式的返回类型由列的 DataType 来确定。Expression 属性的一个用途是创建计算出的列。例如,若要计算税值,就要将单价乘以特定地区的税率。由于各地税率不同,不可能将单一税率放在一个列中;于是便用 Expression 属性来计算这个值,如下面这一部分中的 Visual Basic 代码所示:DataSet1.Tables("Products").Columns("tax").Expression = "UnitPrice * 0.086"第二个用途是创建聚合列。类似于计算出的值,聚合基于 DataTable 中的整个行集执行操作。一个简单的示例就是计算该集中返回的行数。这便是您将用来计算特定销售人员所完成的交易数的方法,如下面的 Visual Basic 代码所示:DataSet1.Tables("Orders").Columns("OrderCount").Expression = "Count(OrderID)";
表达式语法
在创建表达式时,使用 ColumnName 属性来引用列。例如,如果一个列的 ColumnName 是“UnitPrice”,而另一个是“Quantity”,则表达式将是:

"UnitPrice * Quantity"

4、DataTable成员之DataView

DataView类似数据库中的视图。 

DataView 使您能够创建 DataTable 中所存储的数据的不同视图,这种功能通常用于数据绑定应用程序。使用 DataView,您可以使用不同排序顺序显示表中的数据,并且可以按行状态或基于筛选器表达式来筛选数据。

DataView 提供基础 DataTable 中的数据的动态视图:内容、排序和成员关系会实时反映其更改。此行为不同于 DataTable 的 Select 方法,后者从表中按特定的筛选器和/或排序顺序返回 DataRow 数组,虽然其内容反映对基础表的更改,但其成员关系和排序却则保持静态。DataView 的动态功能使其成为数据绑定应用程序的理想选择。
与数据库视图类似,DataView 为您提供了可向其应用不同排序和筛选条件的单个数据集的动态视图。但是,与数据库视图不同的是,DataView 不能作为表来对待,无法提供联接的表的视图。另外,还不能排除存在于源表中的列,也不能追加不存在于源表中的列(如计算列)。

在实际运用中,我们时常使用如下代码:

DataView dv = dt.DefaultView;
dv.Sort = "UserName"; //根据UserName排序,得到新的DataView

DataTable dtNew=dv.ToTable();//将DataView重新转为DataTable

4.1 DataViewRowState:

其实DataView是类似于DataTable,它里面也有RowState,我们可以使用RowStateFilter来过滤不同状态的行。































currentRows包括所有未更新的、新的和修改的数据行Deleted所有自上次调用AcceptChanges后删除的数据行ModifiedCurrent所有自上次调用AcceptChanges后修改过的数据行ModifiedOriginal所有自上次调用AcceptChanges后original版本的数据行New所有自上次调用AcceptChanges后新添加的行OriginalRows返回初始数据行,包含unchanged和deleted 的Unchanged所有未更新的数据行
 

4.2 DataView的过滤器

设置过滤 RowFilter是一个可读写的属性,用来读取和设置表过滤的表达式。public virtual string RowFilter {get; set;}

 你可以用列名,逻辑和数字运算符和常量的任意合法组合组成表达式。以下是一些例子:
dv.RowFilter = "Country = 'USA'";
dv.RowFilter = "EmployeeID >5 AND Birthdate < #1/31/82#"
dv.RowFilter = "Description LIKE '*product*'"

让我们来看一下过滤器的基本规则和运算符。
过滤字符串是表达式的逻辑连接。可以用AND,OR,NOT来连接成一个较短的表达式,也可以使用圆括号来组成子句,指定优先的运算。
通常包含列名的子句同字母、数字、日期或另一个列名进行比较。这里,可以使用关系运算符和算术运算符,如>=, <, >, +, *, % (取模)等等。
如果要选取的行并不能方便地通过算术或逻辑运算符表达,你可以使用IN操作符。以下代码显示如何选取一个随机行:
dv.RowFilter = "employeeID IN (2,4,5)"

你也可以使用通配符*和%,它们同LIKE运算符一起使用时显得更有用。它们都表示任意数量的字符,可以相互替代使用。
请注意,如果在LIKE子句中已经有了*或%字符,你必须用方括号将其括起,以免歧义。如果很不幸,字符串中方括号本身也存在了,那么它也必须用将本身括起。这样,匹配语句会如下所示:
dv.RowFilter = "Description LIKE '[[]*[]]product[[]*[]]"

通配符只允许在过滤字符串的开头或结尾处使用,而不能在字符串中间出现。例如,下列语句会产生运行时错误:
dv.RowFilter = "Description LIKE 'prod*ct"

字符串必须以单引号括起,而日期型必须以#符号括起。字符型值可以使用小数点和科学计数法。
RowFilter也支持聚合函数,如SUM, COUNT, MIN,MAX, and AVG。如果表中没有数据行,那么函数将返回NULL。
在介绍RowFilter表达式的最后,让我们讨论三个很便利的函数:Len,IIF和Substring。
正如其名,Len()返回特定表达式的长度。该表达式可以是一个列名,也可以是其他合法的表达式。
Substring()返回指定的表达式自特定位置开始,特定长度的字符子串。
我最喜欢用的是IIF(),它按照逻辑表达式的值有一到两个值。IIF是IF-THEN-ELSE语句的紧凑表达。语法如下:
IIF(expression, if_true, if_false)

通过该函数,可以建立非常复杂的过滤字符串。例如,假定你从SQL Server的Northwind数据库中取得Employees表,下列表达式可以选出那些employeeID小于6且lastname为偶数个字符和employeeID大于6且lastname为奇数个字符的员工。
IIF(employeeID<6, Len(lastname) %2 =0, Len(lastname) %2 >0)

4.3 DataView 的排序

DataView支持Sort属性,可以用来对视图中的内容排序。Sort由用逗号分隔的列名表达式进行排序。通过在任何列名后加ASC或者DESC限定词,可以使得字段按照上升或者下降的顺序排列。如果没有方向限定词,默认顺序为ASC。
DataView是内存中的对象,所以排序在本地进行,无需调用数据库服务器。

实例篇

实例1.DataTable分组统计数据

































NameSubjectScoresJack00190Jack00285.5Tom00178.5Jerry00159Tom002100
 

 如上表是dt中的数据,如果要分组进行统计各学生的平均科目成绩,

可以使用如下的方法(当然如果你的.Net版本支持Linq的话,可以使用Linq)

思路:找出所有的学生,遍历表,计算该学生的平均成绩,参考代码如下:
//获取所有的学生
DataView myDataView = new DataView(dt);
string[] strComuns ={ "Name"};
DataTable dtTemp = myDataView.ToTable(true, strComuns);
//新建DataTable存储结构,结构同dt
DataTable  dtNew=dt.Clone();
//根据学生统计数据
for (int i = 0; i < dtTemp.Rows.Count; i++)
{
DataRow drDetail = dtNew.NewRow();
drDetail["Name"] = dtTemp.Rows[i]["Name"].ToString();
drDetail["Scores"] = dt.Compute("AVG(Scores)", "Name='" + dtTemp.Rows[i]["Name"].ToString() + "'");
dtNew.Rows.Add(drDetail);
}

转载自: http://www.cnblogs.com/alexis/archive/2010/09/18/1830036.html

程序员,对自己好一点

昨天在Google图片中输入“程序员”,搜索到的第一张图片是这样的

 
一位平头兄桌上两台笔记本一台台式机。其中的一台中显示是某个论坛的页面【估计正在回答某个问题】、中间那台正在启动Eclipse【要开始写Java程序了】、平头兄的目光此时盯在台式机的显示器上【应该是正在远程或者是某个虚拟机】,旁边还有一本打开的书…

图片的名字是“真正的程序员就应该这样”,程序员就应该这样么?

是谁规定程序员就应该是这样的,本来是应该四个人做的事情让一个程序员做,难道程序员是四核的?

作为程序员中的一份子,我时刻注意对自己好一点。

穿着

下面两张图片是恶搞程序员的,虽然还没那么夸张,不过确实有那么点意思





现在的程序员跟不修边幅的艺术家很像,不同的是人家玩是艺术,我们写的是寂寞!

我们不用穿的很花哨,但是至少是得体!不要留给别人不好的印象,好像我们程序员现在就像民工一样【PS:不是诋毁民工同胞】

熟话说,“佛靠金装,人靠衣装”。我们程序员也需要稍微打扮下自己。

情感方面

微软曾经为Visual Studio 2010 做过一个煽情的广告,推出了以恋爱为主题的五个视频:

第一幕——《想做你的Code》:“爱上一个VC,做你下一行Code”。
第二幕——《让爱延长》:“幸福能run多久?有时候一分钟就够”,“更高效的C++,更多时间留给爱”。
第三幕——《幸福也要敏捷》:“约好的幸福,为什么总要一等再等?更多敏捷特性,更快响应爱的需要”。
第四幕——《为爱Debug》:“当爱有了Bug”我们的主人公能否成功Debug呢?”
第五幕——《让爱编译通过》:“不是每份爱都能编译通过,我想我就是那个幸运儿。”

相信很多微软的粉丝都已经看过了,没有看过的可以去优酷里看看 http://www.youku.com/playlist_show/id_4584315.html




这是一部分程序员的真实情况。但,绝大多是程序员一直保留着处子之身。想旁边有个漂亮的女孩,想都别想。恐怖的说法是,鬼都不会找程序员!

年轻的程序员们,好好把握住自己身边的好女孩们,不要到后来发出这样的感慨“曾经有一份真挚的爱情摆在我面前,但是我没有珍惜,【因为我是程序员】。等到了失去的时候才后悔莫及,尘世间最痛苦的事莫过于此。如果老天可以再给我一个再来一次的机会,【我再也不做程序员了】”…

曾经在人人看到这样一条状态,出自我的一个也是程序员的同学“如果你的朋友很久没联系你了,有两种可能:一是死了,另一种是学通信或者电子或者计算机... ”。我们要经常跟家人、朋友沟通,要时不时的打个电话给他们。还有我们的父母,我们要每隔一段时间打个电话给他们,免得他们牵挂!

程序员,记住,我们不是Machine,我们是Human,我们不只是需要跟Machine沟通,我们更需要跟Human的沟通!

饮食方面

 泡面是程序员的主食之一,因为方便面很是方便,一盒面,一瓶开水就能填饱肚子。



 众所周知,方便面是垃圾食品,方便面盐分过高,含防腐剂、香精,损肝;只有热量,没有营养 。长期食用对身体有害无益。但是,我们程序员却钟爱方便面,原因无他,吃饭吃耗时最短,又能边编程的食品。曾经有说法"最容易受伤的是男人的胃",我想这男人中80%的是程序员。

程序员,请为你的家人想想吧, 吃些健康的食物吧。

下面是网上收集的有益于程序员健康的食物
代码

程序员的饮食应该如何安排—高蛋白食品抗辐射,动物肝脏和新鲜蔬果保护眼睛,富含钾、氨基酸等元素的食品健脑。
如今,电脑越来越普及,许多人不仅在单位使用,家里也安装了电脑,由于操作时间不断延长,一些疾病也随之而来。
日前,室内设计师张先生因为每天与电脑为伍十几个小时而肩酸背痛,眼睛酸肿,动不动就感冒,咨询了一些医生后,他得到了一张“菜单”,医生告诉他,只要合理安排一日三餐,身体状况将大大改善。这份特殊的菜单是这样的,早餐应吃营养充分,有足够热量的食物,能保证旺盛的精力。

高蛋白食品:抗辐射

中餐多吃蛋白质高的东西,如瘦猪肉、牛肉、鸡鸭、动物内脏、鱼和豆制品等,晚餐就要多吃维生素高的食物,各种新鲜蔬菜,新鲜水果,还有含磷高的小食如虾、鱼、蛋黄、核桃、花生。此外,多喝水可以保证电脑操作者身体内不缺水,茶叶中含有茶多酚等活性物质,有吸收及抵抗放射性物质的作用。

动物肝脏和新鲜蔬果:护眼

经常看电脑容易损伤眼睛,饮食上要有意识地多选保护眼睛的食物,防止近视和其他眼疾。健眼的食物有各种动物肝脏、红枣、牛奶、奶油、小米、胡萝卜、青菜、菠菜、大白菜、番茄、黄花菜、空心菜、枸杞子和各种新鲜水果。工作1至2个小时后,活动一下身体,做做眼保健操。

富含钾、氨基酸、维B的食品:健脑

因为精神集中大脑高度紧张而造成的脑疲劳,平时可以加强三种元素的食物。

一种是含钾元素的食品:钾元素可直接连通大脑神经,可使大脑神经介质正常有序地工作,确保大脑轻松,粗粮、土豆、坚果、香蕉、荸荠、杏、柑橘、牛奶等富含钾元素。

另一种是含氨基酸的食品:全麦面包、蜂蜜、葵花子、银耳、奶类、羊肉、鸡肉被人体吸收后,蛋白质中的氨基酸进入大脑,有镇静剂的功效。

第三种就是含维生素B和钙的食品:人在焦虑不安、郁郁寡欢、情绪不稳时,体内缺乏维生素B,含维生素B高的食物是鱼,多吃鱼对调节情绪大有益处,其次是土豆和牛肉。含钙的食物有大豆、菠菜、花生、芝麻、冬苋菜、海带、虾、奶类,也要多吃一些。


 

生活起居方面



程序员大都是夜猫子,一般都是12点后才睡觉的.于是就有上面的这幅图片。

晚上十一点到早上一点,那是肝脏排毒的时间,我们程序员通常在这段时间还活跃着,写博客、看教程、看视频、打游戏…此时的我们的大脑还处在兴奋状态,肝脏不能很好的排毒,带来的恶性结果是:我们的皮肤变得很差,身体抵抗力下降。

我们不一定要到很晚的时候才睡觉,有人说,我这个bug还没搞定呢,睡不着呢!我很欣赏这种一丝不苟的态度,却反对时常性的为了一个bug而搞到很晚!

各器官排毒工作时间如下:
代码

晚上9点~晚上11点: 免疫系统(淋巴)排毒时间

排毒对策:此段时间应该安静或听音乐,这时精神紧张或者焦虑对健康是不利的唷

晚上11点~早上1点:肝脏排毒时间

排毒对策:这几小时里面也就是大家所谓的美容觉唷!让肝脏得到适当的休息,对您的皮肤,还有健康都是非常有帮助的,这段时间若都不睡的话,皮肤会变得比较差及抵抗力低落等等唷!所以一定要好好利用这段时间睡个美容觉喔

早上1点~早上3点:胆的排毒

排毒对策:此段时间应好好熟睡,对胆汁分泌帮助会比较大喔

早上3点~早上5点:肺的排毒时间

排毒对策:这就是为甚么咳嗽的人总是在这段时间咳的最剧烈的原因啰!因为此时的排毒动作已经走到肺部,所以哮喘气喘等最容易发生的时间也是都在这时段比较多,此时若是自然排毒的话,不应该服用止咳药,以免抑制废积物的排除~

早上5点~早上7点:大肠的排毒

排毒对策:这段时间应该空腹多喝温开水,让大肠得到适当的滋润,并促进肠道的蠕动,有助于宿便的排出,对身体健康是非常有帮助的唷!加点盐巴的温开水并按摩腹部(请以正确的按摩方向才可以唷!)对于排便是很有帮助的喔!宿便是减重的杀手,所以一定要养成每天顺利排便的好习惯~ 早上7点~早上9点:小肠大量吸收营养的时段

排毒对策:应吃早餐的最佳时间唷!减重千万不要以为早上都不吃就可以了,这样反而会因为晚上吃下更多东西而囤积脂肪更容易胖起来的唷!正确应该在这段时间好好享用营养丰富的早餐,若是疗病者最好提早吃(在6点半前),养生者则建议在早上7点半前,不吃早餐者应改变习惯养成吃早餐的习惯,即使拖到早上10点,吃都会比不吃还要来的好喔


 别让我们的器官长期超负荷工作! 请早点睡吧!

健康方面

今天看NBA的时候,主持人介绍了NBA的八大玻璃人。姚明和麦迪榜上有名,NBA最容易碎的玻璃人是开拓者的格雷格-奥登,这个赛季再次报销。NBA中受伤在所难免,那么激烈的身体对抗,磕磕碰碰也是正常事。但是,作为程序员的我们,又不跟谁打架,为什么那么脆弱?

由中华医院管理学会、中国医师协会、北京慈济健康体检连锁机构联合发布的“健康透支十大行业”社会调查结果显示,IT和企业高管人群中透支现象最为严重,亚健康比例分别为91%和86%;其次为媒体记者、证券、保险、出租车司机、交警、销售、律师、教师行业。

时常在园子里看到说一些不幸的消息,如某某癌症晚期….联想到前阵子有同事生病请病假,听项目经理感叹说道:程序员是很容意受伤的。确实是这样,长期缺乏运动的我们,亚健康指数如同for循环的i,一直在做着++的运算…。“我们没有时间运动”,可能一些程序员抱怨道。我想引用鲁迅先生的原话,“时间就像海棉里的水,只要肯挤总是有的”,只要你想运动,什么时候都可以。如,每天早上跑步去公交站台,中午吃饭饭了,出去溜达溜达….

给大家一些网上收集的Tips:
代码

早操:

第一节头部运动

双手掐腰,头部顺时针缓慢旋转8拍,换逆时针旋转8拍

第二节手部运动

左臂前伸,手掌向上,右手握住左手四指,向下压8拍,换手

第三节臂部运动

左臂前伸,右臂抱住左臂上臂,向左压8拍,换右臂

第四节腰部运动

双手掐腰,后仰8拍,前躬8拍

早晨开始工作前先喝杯浓咖啡, 有助头脑清醒、精神抖擞,但须先吃早餐后,才能饮用,否则易伤及肠胃。

 

午后:

有些程序员喜欢午睡. 午睡的确可以使精力得到恢复,下午及晚上的工作学习更有精神.但是伏案暂睡片刻,以解疲劳这种方法不可取,往往醒后会出现暂时性的视力模糊,因为伏案睡觉会压迫眼球,造成眼压过高,倘若每天如此,会使眼球胀大、眼轴增长,形成高度近视,使视力受到损害。 所以,午睡应该躺在床上,荐与大多数程序员都没有条件, 吃完午饭后还是,呼吸呼吸新鲜空气,保持一下午清醒的头脑工作更好.如果已养成午睡习惯,那么请注意:

不要饭后即睡:一般午睡时间安排到午饭后半小时为好,不要饭后即睡 因为刚吃了午饭,胃内充满食物,消化机能正处于运动状态,这时午睡会影响肠胃的消化。
午睡时间不要太长:为使午睡对人体有益而不影响晚上睡眠,以午睡30~60分钟为宜,睡的太长对身体没有好处。 坐着打盹替代午睡不利于消除疲劳。因为人体处于睡眠状态时,全身肌肉松弛,血液循环减慢,头部供血减少。坐着午睡由于体位关系,供给大脑的血液更少,使人醒后易出现头昏、眼花、乏力等一系列大脑缺血缺氧的症状,所以这种午睡方式是不合乎健康要求的。

 

睡前运动:

请买32KG组合式哑铃
第一周使用16KG的
1、过头挺举 15~20次 3组
2、平肩推举 5~10次 2组
3、俯卧推举 15~25次 3组
4、哑铃弯举 20~25次 3组

适量的体育运动,能够促进人的大脑分泌出抑制兴奋的物质,促进深度睡眠,迅速缓解疲劳,并从而进入一个良性循环。但过量运动带来的疲劳,将导致大脑过度兴奋,适得其反。这里所指的运动量是因人而异的。

 

许多程序员都有肩周炎,程序员整天对这电脑,每日每夜,长期的劳作,容易导致肩周炎。像预防肩周炎很简单,那就是多做耸肩运动:坐姿,双手搭在肩部,双臂作扩张、旋转运动,可防肩周炎。




 

社会中的地位

程序员的社会是低下的,在网上流传着这么一个说法“程序员被誉为IT农民工”。




曾经看到这样的类比,将程序员跟妓女相比,原文如下:
代码

程序员与妓女基本一样,以下为证:

1、都是靠出卖为生。

2、吃青春饭,人老珠黄肯定混不下去。

3、越高级收入越高,当然中间人的抽头会更高。

4、生活没有规律。以夜生活为主,如果需要,凌晨也要加班。

5、名声越大,越容易受到青睐。

6、必须尽最大可能满足客户各种各样非正常的需求。

7、鼓励创新精神。

8、喜欢扎堆。程序员集中的地方称为软件园,妓女集中的地方叫红灯区。

9、流动性较大,正常情况下没有工会。

10、如果怀孕了,既不能做程序员,也不能做妓女。

11、都为防病毒的问题而烦恼...

12、当然, 个中高手还专门以制毒传毒为乐。

13、一个是Microsoft,一个是Plug & Play。

14、工作状态相同。工作时精神高度集中,最怕外界干扰。工作完毕身心放松,体会到一种不可替代的工作快乐。

15、女孩子最好还是不要做这两个职业,但还是有很多女孩子做。

16、除非在转行以后,否则都不愿意结婚......没空儿啊。

17、程序员怕查户口的。妓女怕查房的。

18、妓女工作的地方(床)是程序员最向往的地方。

19、程序界的高手通常很讨厌微软,妓女界的高手嗯...这个...恐怕也如此。

20、都是吃青春饭,不过到人老珠黄后,凭着混个脸熟,程序员可以混个管理员,妓女也行,不过俗称老鸨。

21、妓女靠的本钱是三围,程序员靠的可是四围(思维)。

22、程序员为了拉客,通常会在交易前提供一个DEMO,妓女提供的那叫PHOTO。

23、程序员现在出的活时兴叫吃霸、结霸,妓女大姐一律叫波霸。

24、心不在焉的妓女可以一边工作一边do { beep(1); sleep(9) } until overflow。心不在焉的程序员也可以一边工作一边navigate到**(不当用词)上去。 25、程序员手册:一套好的人机操作界面要求,对于新手,能够一步一步的引导他进入功能,相反对于熟客,能够直奔主题;妓女同样要遵守程序员手册对人鸡界面的规定。

26、妓女在工作中最怕的是临检,程序员最怕的是停电。

27、新上手的程序员叫菜鸟,刚入行的妓女叫雏鸡,都是好可怜的小动物。

28、程序界现在流行OO的方法,虽然在XXXX年前妓女已在床上掌握了O~O~~~的技术。

29、程序员为了拉客,无奈之时,也可以先让客人试玩,妓女当然有时也会先给你甜头。

不过总之程序员比妓女还惨,补充如下: 1、妓女每个月总有几天可以理直气壮的说不,程序员如果老板不发话,可要一年干到黑。 2、女人做程序那叫奇女、才女,男人要是做妓,那就叫鸭了。 3、妓女不干了人家那叫从良,程序员如果不干了,估计是下了岗。 4、程序员有千年虫问题,妓女好象没听说有。 5、妓女的工作隐蔽性很强,程序员的工作只怕亲戚朋友都知道,所以更加没脸皮。 6、程序员做的越好,要做的程序越多,妓女做的好,就可以挑三拣四。 7、程序员现在流行FREE、OPEN什么的,说白了就是自己玩自己,妓女界好象还没这样恶性竞争。


 

劳力者下,劳智者中,劳人者上

我们大部分程序员现在做的是劳力活动,即第一类,我们其中的一部分可能需要正在向劳人者努力,有些人可能永远是劳力者…

我发现许多程序员动手时间和动脑时间之比都在9:1以上,优秀的程序员动手时间和动脑时间之比应该在7:3以下。当其比值下降到5:5、3:7以下程序员也就完成了向系统设计人员转变的准备。

给大家一点Tips:天时不如地利,地利不如人和!多想,谋而后动!
这里向大家推荐一篇不错的文章。如果大家E文很好的话,可以看下这篇文章《There Are No Famous Programmers》 http://sheddingbikes.com/posts/1275989245.html

也有翻译为中文的《世上没有“著名程序员” 》 http://www.aqee.net/2010/06/23/there-are-no-famous-programmers/




程序员,请对自己好一点!

c# 网络编程初探

我们知道 C#和C++的差异之一,就是他本身没有类库,所使用的类库是.Net框架中的类库--.Net FrameWork SDK。在.Net FrameWork SDK中为网络编程提供了二个名称空间:"System.Net"和"System.Net.Sockets"。 C#就是通过这二个名称空间中封装的类和 方法 实现网络通讯的。 

首先我们解释一下在网络编程时候,经常遇到的几个概念:同步(synchronous)、异步(asynchronous)、阻塞(Block)和非阻塞(Unblock):

所谓同步方式,就是发送方发送数据包以后,不等接受方响应,就接着发送下一个数据包。异步方式就是当发送方发送一个数据包以后,一直等到接受方响应后, 才接着发送下一个数据包。而阻塞套接字是指执行此套接字的网络调用时,直到调用成功才返回,否则此套节字就一直阻塞在网络调用上,比如调用 StreamReader 类的Readlin ( )方法读取网络缓冲区中的数据,如果调用的时候没有数据到达,那么此Readlin ( )方法将一直挂在调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指在执行此套接字的网络调用时,不管是否执行成功,都立即返回。同样调用 StreamReader 类的Readlin ( )方法读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在Windows网络通信软件开发中,最为常用的方法就是异步非 阻塞套接字。平常所说的C/S(客户端/服务器)结构的软件采用的方式就是异步非阻塞模式的。

其实在用 C#进行网络编程中,我们并不需要了解什么同步、异步、阻塞和非阻塞的原理和工作机制,因为在.Net FrameWrok SDK中已经已经把这些机制给封装好了。下面我们就用 C#开一个具体的网络程序来说明一下问题。

一.本文中介绍的程序设计及运行环境
(1).微软视窗2000 服务器版
(2)..Net Framework SDK Beta 2以上版本
二. 服务器端程序设计的关键步骤以及解决办法:
在下面接受的程序中,我们采用的是异步阻塞的方式。
(1).首先要要在给定的端口上面创建一个"tcpListener"对象侦听网络上面的请求。当接收到连结请求后通过调用 "tcpListener"对象的"AcceptSocket"方法产生一个用于处理接入连接请求的Socket的实例。下面是具体 实现代码:

//创建一个tcpListener对象,此对象主要是对给定端口进行侦听
tcpListener = new TcpListener ( 1234 ) ;
//开始侦听
tcpListener.Start ( ) ;
//返回可以用以处理连接的Socket实例
socketForClient = tcpListener.AcceptSocket ( ) ;

(2).接受和发送客户端数据:

此时Socket实例已经产生,如果网络上有请求,在请求通过以后,Socket实例构造一个"NetworkStream"对象, "NetworkStream"对象为网络访问提供了基础数据流。我们通过名称空间"System.IO"中封装的二个类"StreamReader"和 "StreamWriter"来 实现对"NetworkStream"对象的访问。其中"StreamReader"类中的ReadLine ( )方法就是从"NetworkStream"对象中读取一行字符;"StreamWriter"类中的WriteLine ( )方法就是对"NetworkStream"对象中写入一行字符串。从而 实现在网络上面传输字符串,下面是具体的 实现代码:

try
{
//如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
if ( socketForClient.Connected )
{
ListBox1.Items.Add ( "已经和客户端成功连接!" ) ;
while ( true )
{
//创建networkStream对象通过网络套节字来接受和发送数据
networkStream = new NetworkStream ( socketForClient ) ;
//从当前数据流中读取一行字符,返回值是字符串
streamReader = new StreamReader ( networkStream ) ;
string msg = streamReader.ReadLine ( ) ;
ListBox1.Items.Add ( "收到客户端信息:" + msg ) ;
streamWriter = new StreamWriter ( networkStream ) ;
if ( textBox1.Text != "" )
{
ListBox1.Items.Add ( "往客户端反馈信息:" + textBox1.Text ) ;
//往当前的数据流中写入一行字符串
streamWriter.WriteLine ( textBox1.Text ) ;
//刷新当前数据流中的数据
streamWriter.Flush ( ) ;
}
}
}
}
catch ( Exception ey )
{
MessageBox.Show ( ey.ToString ( ) ) ;
}
(3).最后别忘了要关闭所以流,停止侦听网络,关闭套节字,具体如下:

//关闭线程和流
networkStream.Close ( ) ;
streamReader.Close ( ) ;
streamWriter.Close ( ) ;
_thread1.Abort ( ) ;
tcpListener.Stop ( ) ;
socketForClient.Shutdown ( SocketShutdown.Both ) ;
socketForClient.Close ( ) ;

三. C#网络编程 服务器端程序的部分源代码(server. cs):

由于在此次程序中我们采用的结构是异步阻塞方式,所以在实际的程序中,为了不影响 服务器端程序的运行速度,我们在程序中设计了一个线程,使得对网络请求侦听,接受和发送数据都在线程中处理,请在下面的代码中注意这一点,下面是server. cs的完整代码:

using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Net.Sockets ;
using System.IO ;
using System.Threading ;
using System.Net ;
//导入程序中使用到的名字空间
public class Form1 : Form
{
private ListBox ListBox1 ;
private Button button2 ;
private Label label1 ;
private TextBox textBox1 ;
private Button button1 ;
private Socket socketForClient ;
private NetworkStream networkStream ;
private TcpListener tcpListener ;
private StreamWriter streamWriter ;
private StreamReader streamReader ;
private Thread _thread1 ;
private System.ComponentModel.Container components = null ;
public Form1 ( )
{
InitializeComponent ( ) ;
}
//清除程序中使用的各种资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
label1 = new Label ( ) ;
button2 = new Button ( ) ;
button1 = new Button ( ) ;
ListBox1 = new ListBox ( ) ;
textBox1 = new TextBox ( ) ;
SuspendLayout ( ) ;
label1.Location = new Point ( 8 , 168 ) ;
label1.Name = "label1" ;
label1.Size = new Size ( 120 , 23 ) ;
label1.TabIndex = 3 ;
label1.Text = "往客户端反馈信息:" ;
//同样的方式设置其他控件,这里略去

this.Controls.Add ( button1 ) ;
this.Controls.Add ( textBox1 ) ;
this.Controls.Add ( label1 ) ;
this.Controls.Add ( button2 ) ;
this.Controls.Add ( ListBox1 ) ;
this.MaximizeBox = false ;
this.MinimizeBox = false ;
this.Name = "Form1" ;
this.Text = " C#的网络编程 服务器端!" ;
this.Closed += new System.EventHandler ( this.Form1_Closed ) ;
this.ResumeLayout ( false ) ;

}
private void Listen ( )
{
//创建一个tcpListener对象,此对象主要是对给定端口进行侦听
tcpListener = new TcpListener ( 1234 ) ;
//开始侦听
tcpListener.Start ( ) ;
//返回可以用以处理连接的Socket实例
socketForClient = tcpListener.AcceptSocket ( ) ;
try
{
//如果返回值是"true",则产生的套节字已经接受来自远方的连接请求
if ( socketForClient.Connected )
{
ListBox1.Items.Add ( "已经和客户端成功连接!" ) ;
while ( true )
{
//创建networkStream对象通过网络套节字来接受和发送数据
networkStream = new NetworkStream ( socketForClient ) ;
//从当前数据流中读取一行字符,返回值是字符串
streamReader = new StreamReader ( networkStream ) ;
string msg = streamReader.ReadLine ( ) ;
ListBox1.Items.Add ( "收到客户端信息:" + msg ) ;
streamWriter = new StreamWriter ( networkStream ) ;
if ( textBox1.Text != "" )
{
ListBox1.Items.Add ( "往客户端反馈信息:" + textBox1.Text ) ;
//往当前的数据流中写入一行字符串
streamWriter.WriteLine ( textBox1.Text ) ;
//刷新当前数据流中的数据
streamWriter.Flush ( ) ;
}
}
}
}
catch ( Exception ey )
{
MessageBox.Show ( ey.ToString ( ) ) ;
}
}
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}

private void button1_Click ( object sender , System.EventArgs e )
{
ListBox1.Items .Add ( "服务已经启动!" ) ;
_thread1 = new Thread ( new ThreadStart ( Listen ) ) ;
_thread1.Start ( ) ;

}

private void button2_Click ( object sender , System.EventArgs e )
{
//关闭线程和流
networkStream.Close ( ) ;
streamReader.Close ( ) ;
streamWriter.Close ( ) ;
_thread1.Abort ( ) ;
tcpListener.Stop ( ) ;
socketForClient.Shutdown ( SocketShutdown.Both ) ;
socketForClient.Close ( ) ;
}
private void Form1_Closed ( object sender , System.EventArgs e )
{
//关闭线程和流
networkStream.Close ( ) ;
streamReader.Close ( ) ;
streamWriter.Close ( ) ;
_thread1.Abort ( ) ;
tcpListener.Stop ( ) ;
socketForClient.Shutdown ( SocketShutdown.Both ) ;
socketForClient.Close ( ) ;
}
}

四.客户端程序设计的关键步骤以及解决办法:

(1).连接到 服务器端的指定端口:

我们采用的本地机既做服务器也做客户机,你可以通过修改IP地址来确定自己想要连接的服务器。我们在连接的时候采用了"TcpClient"类,此类 是在较高的抽象级别(高于Socket类)上面提供TCP服务。下面代码就是连接到本地机(端口为1234),并获取响应流:

//连接到 服务器端口,在这里是选用本地机器作为服务器,你可以通过修改IP地址来改变服务器
try
{
myclient = new TcpClient ( "localhost" , 1234 ) ;
}
catch
{
MessageBox.Show ( "没有连接到服务器!" ) ;
return ;
}
//创建networkStream对象通过网络套节字来接受和发送数据
networkStream = myclient.GetStream ( ) ;
streamReader = new StreamReader ( networkStream ) ;
streamWriter = new StreamWriter ( networkStream ) ;

(2). 实现接受和发送数据:

在接受和发送数据上面,我们依然采用了"NetworkStream"类,因为对他进行操作比较简单,具体 实现发送和接受还是通过命名空间 "System.IO"中"StreamReader"类ReadLine ( )方法和"StreamWriter"类的WriteLine ( )方法。具体的 实现方法如下:

if ( textBox1.Text == "" )
{
MessageBox.Show ( "请确定文本框为非空!" ) ;
textBox1.Focus ( ) ;
return ;
}
try
{
string s ;
//往当前的数据流中写入一行字符串
streamWriter.WriteLine ( textBox1.Text ) ;
//刷新当前数据流中的数据
streamWriter.Flush ( ) ;
//从当前数据流中读取一行字符,返回值是字符串
s = streamReader.ReadLine ( ) ;
ListBox1.Items.Add ( "读取 服务器端发送内容:" + s ) ;
}
catch ( Exception ee )
{
MessageBox.Show ( "从 服务器端读取数据出现错误,类型为:" + ee.ToString ( ) ) ;
}
(3).最后一步和 服务器端是一样的,就是要关闭程序中创建的流,具体如下:

streamReader.Close ( ) ;
streamWriter.Close ( ) ;
networkStream.Close ( ) ;

五.客户端的部分代码:

由于在客户端不需要侦听网络,所以在调用上面没有程序阻塞情况,所以在下面的代码中,我们没有使用到线程,这是和 服务器端程序的一个区别的地方。总结上面的这些关键步骤,可以得到一个用 C#网络编程 完整的客户端程序(client. cs),具体如下:

using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Net.Sockets ;
using System.IO ;
using System.Threading ;
//导入程序中使用到的名字空间
public class Form1 : Form
{
private ListBox ListBox1 ;
private Label label1 ;
private TextBox textBox1 ;
private Button button3 ;
private NetworkStream networkStream ;
private StreamReader streamReader ;
private StreamWriter streamWriter ;
TcpClient myclient ;
private Label label2 ;

private System.ComponentModel.Container components = null ;

public Form1 ( )
{
InitializeComponent ( ) ;
}
//清除程序中使用的各种资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
label1 = new Label ( ) ;
button3 = new Button ( ) ;
ListBox1 = new ListBox ( ) ;
textBox1 = new TextBox ( ) ;
label2 = new Label ( ) ;
SuspendLayout ( ) ;
label1.Location = new Point ( 8 , 168 ) ;
label1.Name = "label1" ;
label1.Size = new Size ( 56 , 23 ) ;
label1.TabIndex = 3 ;
label1.Text = "信息:" ;
//同样方法设置其他控件
AutoScaleBaseSize = new Size ( 6 , 14 ) ;
ClientSize = new Size ( 424 , 205 ) ;
this.Controls.Add ( button3 ) ;
this.Controls.Add ( textBox1 ) ;
this.Controls.Add ( label1 ) ;
this.Controls.Add ( label2 ) ;
this.Controls.Add ( ListBox1 ) ;
this.MaximizeBox = false ;
this.MinimizeBox = false ;
this.Name = "Form1" ;
this.Text = " C#的网络编程客户器端!" ;
this.Closed += new System.EventHandler ( this.Form1_Closed ) ;
this.ResumeLayout ( false ) ;
//连接到 服务器端口,在这里是选用本地机器作为服务器,你可以通过修改IP地址来改变服务器
try
{
myclient = new TcpClient ( "localhost" , 1234 ) ;
}
catch
{
MessageBox.Show ( "没有连接到服务器!" ) ;
return ;
}
//创建networkStream对象通过网络套节字来接受和发送数据
networkStream = myclient.GetStream ( ) ;
streamReader = new StreamReader ( networkStream ) ;
streamWriter = new StreamWriter ( networkStream ) ;
}
static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}

private void button3_Click ( object sender , System.EventArgs e )
{

if ( textBox1.Text == "" )
{
MessageBox.Show ( "请确定文本框为非空!" ) ;
textBox1.Focus ( ) ;
return ;
}
try
{
string s ;
//往当前的数据流中写入一行字符串
streamWriter.WriteLine ( textBox1.Text ) ;
//刷新当前数据流中的数据
streamWriter.Flush ( ) ;
//从当前数据流中读取一行字符,返回值是字符串
s = streamReader.ReadLine ( ) ;
ListBox1.Items.Add ( "读取 服务器端发送内容:" + s ) ;
}
catch ( Exception ee )
{
MessageBox.Show ( "从 服务器端读取数据出现错误,类型为:" + ee.ToString ( ) ) ;
}
}

private void Form1_Closed ( object sender , System.EventArgs e )
{
streamReader.Close ( ) ;
streamWriter.Close ( ) ;
networkStream.Close ( ) ;

}
}

下图是编译上面二个程序后运行的界面:
图01: C#编写网络程序运行界面
七.总结:

虽然在.Net FrameWrok SDK 中只为网络编程提供了二个命名空间,但这二个命名空间中的内容却是十分丰富的, C#利用这二个命名空间既可以 实现同步和异步,也可以 实现阻塞和非阻塞。本 文通过用 C#编写一个网络上信息传输的程序,展现了其丰富的内容,由于篇幅所限,更深,更强大的功能还需要读者去实践、探索。

转载自: http://www.cnblogs.com/saptechnique/archive/2010/11/24/1886232.html