<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_Rick Carter</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/29293/rss</id><updated>2011-08-11T13:29:02Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/29293/rss"/><entry><id>http://www.cnblogs.com/pains/archive/2011/06/06/2073482.html</id><title type="text">分布式系统设计原理与方案</title><summary type="text">一直在思考分布式系统设计的问题，业务对象原封不动的情况下部署在客户端和服务器端，可以根据配置文件选择是连接服务器还是连接本地的数据库，这个问题让我绞尽脑汁，我总是设想的客户端与服务器端通信的方式是最低端的Socket。花了两个晚上研究CSLA.NET框架关于数据门户这块代码，才发现问题的关键所在：客户端与服务器端通信不能采用最低端的Socket，而要用高端的WebService、.NET Remoting或者是自己定义一种协议等，只要它们支持客户端直接根据服务器端的服务URL、类名、方法名和方法参数四个信息就可以调用服务器对应的类和方法就行。说明：本文中所表达的思想与CSLA.NET有很大区.</summary><published>2011-06-05T21:25:00Z</published><updated>2011-06-05T21:25:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2011/06/06/2073482.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2011/06/06/2073482.html"/><content type="html">&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　一直在思考分布式系统设计的问题，业务对象原封不动的情况下部署在客户端和服务器端，可以根据配置文件选择是连接服务器还是连接本地的数据库，这个问题让我绞尽脑汁，我总是设想的客户端与服务器端通信的方式是最低端的Socket。花了两个晚上研究CSLA.NET框架关于数据门户这块代码，才发现问题的关键所在：客户端与服务器端通信不能采用最低端的Socket，而要用高端的WebService、.NET Remoting或者是自己定义一种协议等，只要它们支持客户端直接根据服务器端的服务URL、类名、方法名和方法参数四个信息就可以调用服务器对应的类和方法就行。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;说明：本文中所表达的思想与CSLA.NET有很大区别，不要看了本文就以为是CSLA.NET的设计思想，也不要以为本文错误的解释了CSLA.NET，这不是一篇介绍CSLA.NET的文章，但纯思想上它们是相同的。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&#xD;
&lt;p&gt;&lt;strong&gt;分布式系统的部署&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;平常我们都说三层架构，我认为它是一个广义的模型，更多层的设计可以合并相邻几层的方式最终回归到三层这个宽泛的概念上来，我的意思是：这些都只是概念，忘记这些概念去实际分析设计会离这些概念更近一些。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;接下来我要把三层变的更简单点，两层，数据访问层合并到业务层，统称为业务层，因为我们面对的问题不是分层的问题，而是分布式系统中各层应该怎么部署的问题。在CSLA.NET书中也说到业务层和数据访问层放到同一台机器上可以提高性能和容错性。因此他们俩的合并不影响分布式系统的部署。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;不过要解释的是数据库系统（CSLA.NET中说的数据存储和管理层）并没有考虑到三层中来，也就是它不包含在数据访问层中，如果把它算进来，那么它是在数据访问层之下单独存在的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;综上，在分布式系统部署角度考虑的分层实际是三层：界面层、业务层（包含数据访问层的业务层）、数据存储层。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;下面举例说明可能的部署情景，&lt;strong&gt;带阴影的框框表示一台机器，虚线框表示根据使用场合可有可无，虚横线表示从此处划开单独出服务器。在B/S应用中，Web浏览器为客户端，其他全部为服务器。在C/S应用中，处在最上层的界面层+业务层为客户端，其他为服务器&lt;/strong&gt;。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;非分布式系统的部署&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524211735.jpg"&gt;&lt;img height="300" width="314" src="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524246487.jpg" alt="单机版" border="0" title="单机版" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;单机版&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524253323.jpg"&gt;&lt;img height="394" width="167" src="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524265700.jpg" alt="分层2" border="0" title="分层2" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;两三台机器&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;分布式系统的部署&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524297845.jpg"&gt;&lt;img height="498" width="545" src="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524331593.jpg" alt="分层3" border="0" title="分层3" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;分布式的Web系统&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524373705.jpg"&gt;&lt;img height="404" width="545" src="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524404704.jpg" alt="分层4" border="0" title="分层4" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p align="center"&gt;分布式的C/S系统&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;有几点要说明：&lt;br /&gt;1． 客户端上的验证等业务逻辑是不可信的，因此任何一种部署都需要服务器端包含业务层；&lt;br /&gt;&lt;span style="color: #ff0000;" color="#ff0000"&gt;&lt;strong&gt;2． 为了开发、维护和部署中的高度可伸缩性，图中的各业务层所包含的代码都是一模一样的；&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;3． 因为第2点，所以我遇到了业务层的同一个操作是与其他机器上的业务层通信还是访问数据库这个难题。&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&lt;strong&gt;解决业务层的数据访问问题&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;这个问题是关键问题，也就是上面几点说明中的第3个问题，为了解决这个问题我们引入数据门户的概念。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;下面以WebService为例说明：界面层访问本机的业务对象的增删改查中的&amp;ldquo;查&amp;rdquo;方法时，跳过数据库的查询操作，访问另一台机器中的同一个业务对象类的&amp;ldquo;查&amp;rdquo;方法。&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524448211.jpg"&gt;&lt;img height="800" width="780" src="http://images.cnblogs.com/cnblogs_com/pains/201106/20110606052448847.jpg" alt="请求" border="0" title="请求" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;以上是向另一台机器发送请求，该请求并不直接调用另一台机器上的业务对象类的&amp;ldquo;查&amp;rdquo;方法，而是将要调用的业务对象和方法参数信息转为一个&amp;ldquo;二进制包&amp;rdquo;，作为参数去调用另一台机器上通用的&amp;ldquo;查&amp;rdquo;方法，另一台机器上的&amp;ldquo;查&amp;rdquo;方法再解开这个包，然后去调用解开的包中所表示的业务对象类型，下面的静态图是另一台机器接受到请求后的工作。&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524524006.jpg"&gt;&lt;img height="726" width="736" src="http://images.cnblogs.com/cnblogs_com/pains/201106/201106060524566085.jpg" alt="响应" border="0" title="响应" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;又有些说明：&lt;br /&gt;1． 关于原理都已在图中做了描述，不另写大段文字解释了；&lt;br /&gt;2． 上面两个图中，除了&amp;ldquo;实际业务对象类&amp;rdquo;以外的部分全部属于架构或者框架部分；&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #ff0000;" color="#ff0000"&gt;3． 如果用OO的思想去审查上面的两个图，你一定会为这糟糕的设计而抱怨，这里只是为了尽可能简单的表述分布式系统的工作原理，你可以采用策略模式使数据门户不改变的情况下适应各种请求响应场合，采用工厂模式实现不同的请求响应场合的切换。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&lt;span style="color: #c0504d;" color="#c0504d"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="color: #c0504d;" color="#c0504d"&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;关于数据库的分布&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: x-small;" size="2"&gt;　　&lt;/span&gt;为了解决数据库服务器的负担，我们可能希望把数据分布存储在多个服务器上，我设想的数据库分布方案是，各服务器上的数据库在结构上一模一样，而表里的数据存储到不同服务器上，这样数据访问层在查数据的时候分别向所有数据库服务器发送同样的sql命令，然后数据访问层得到数据后整合，这样减轻每台服务器的工作量。亦或者根据表里的某个代表性的字段（如：省份）分布数据到不同服务器。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/2073482.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2011/06/06/2073482.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2011/04/29/2032524.html</id><title type="text">重构你的软件企业</title><summary type="text">这里说说自己对一个软件企业的构建和管理的感想，不全面，因为我就一程序员，只能站在普通员工的角度考虑问题，也是站在中国广大小公司的立场思考的，文章标题取的比较大，为了吸引更多人来拍砖。管理上的细节我也不懂，主要就是让每个人都开心，互利互赢，让公司有发展的潜力。</summary><published>2011-04-29T03:00:00Z</published><updated>2011-04-29T03:00:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2011/04/29/2032524.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2011/04/29/2032524.html"/><content type="html">&lt;p&gt;这里说说自己对一个软件企业的构建和管理的感想，不全面，因为我就一程序员，只能站在普通员工的角度考虑问题，也是站在中国广大小公司的立场思考的，文章标题取的比较大，为了吸引更多人来拍砖。管理上的细节我也不懂，主要就是让每个人都开心，互利互赢，让公司有发展的潜力。&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;strong&gt;组织结构的搭配&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;以下角色必不可少。&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;项目经理&lt;/strong&gt;：负责软件的业务流程、团队管理、项目计划和进度、文档、内部和外部的沟通、各种规范的制定、各种选择的最终决策等等。这个角色需要德才兼备，慧眼识金，因为他是最终的决策者，任贤任能，同时还要为部下争取应该有的。&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;架构师&lt;/strong&gt;：任何一个软件企业都需要一个高水平的，能够总揽公司所有产品、所有开发人员的技术水平、知识结构、特长的一个架构师，有了这样的一个人可以在老产品的维护、新产品的开发或者老产品过度到新产品时做技术和方案的选型和繁重的架构工作，以及在公司规划下整合所有产品或者集合所有产品的平台做总体设计的工作，和人力资源的优化，让每个人工作处于饱和状态、发挥所能，同样人力资源下利用率最大化，对开发周期和软件质量都有好处，不至出现有人忙有人闲的情况。如果缺少这样的人，公司在新的时期会遇到一个决定都无法下下来等情况，或者大家像无头苍蝇一样劲不往一处使。&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;产品经理&lt;/strong&gt;：这个角色除了把握公司产品这个大方向外，在他手下还应该有一个测试团队，负责研发出的软件的测试工作，公司软件的发布由产品经理负责，他的决定信息来自他的测试团队，测试团队在对功能、性能等等方面测试后认为软件没问题了，产品经理才会发布软件。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;除了这几个角色外，如果能拥有一些高水平的程序员自然再好不过了。&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;strong&gt;英雄主义的重要性&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;很多人都说现在已经不是英雄主义的时代，这些人要么是人云亦云者，要么是商人、老板、企业高层管理者，因为他们不希望依赖于某个人，谁离开了他们都不担心。但事实上要想做一件足够了不起的事情，总是需要一个人第一个站起来用一流的眼光一流的思想去动手做这件事，其中的各部分也总是需要有人提出更好的解决方案。这些行为就是英雄主义，英雄主义不是逞能，它是激情与思想相碰撞的产物，有时候还需要技术能力做催化剂，是创新的源泉，是创业公司发展的起点。团队的作用就是为了能够拥有更多的英雄，团队合作也是要建立在英雄主义的基础上的，十个二百五恐怕无法组成一个优秀的团队。&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;鼓励创新并给与很高的奖励如果你欣赏的一项创新需要一个部门那就给创新者一个部门，他是头；如果不需要一个部门那就给创新者一个更高的职位或者一个头衔，外加相称的薪资待遇；如果这些都无法给，那么可以给他加薪或者一笔奖励。无论如何荣耀是最主要的，公司或任何个人都不可以剥夺创新者的&amp;ldquo;创始人&amp;rdquo;的荣耀，并且还应该主动的把这个荣耀戴到他头上，无论企业内部还是IT这个行业都去播撒消息承认他的丰功伟绩，比如在公司新闻里写上，无论是浓墨重彩还是一笔带过，即便知道有天他会离开。&lt;/p&gt;&#xD;
&lt;p&gt;作为程序员，职业生涯是短暂的，当他辉煌不在时，一样能够凭借年轻时的创新能力得到其他行业和企业的认可，这就需要此时的企业对他做最大程度的认可，企业会因为更多的创新得到回报，这也是对公正与人才的尊重。&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;strong&gt;公司制度和环境&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;对于制度应本着自由平等的原则，另外该给人办的就给人办了，不要等到员工向公司提要求的时候才去解决他的要求。环境就依照宽松舒适方便，最主要是方便沟通，同一项目组的人方便走动交流，会议室应有多个，大小都有，墙壁上就别挂什么广告类的东西了，放点艺术类的画也比放广告和企业宣传等的好，留些空位放开发中的图纸，如用例图和类图等。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/2032524.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2011/04/29/2032524.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2011/03/22/1991325.html</id><title type="text">作为开发人员，我们实在是太幸运</title><summary type="text">之前看过一个电影，说的是抢运钞车，虽然是违法行为，这也是人家的工作。但这份工作的复杂度就太高了，不仅是黑客（侵入交通系统控制红绿灯），还得是建筑师、机械师、电焊工，以及各种枪 支 弹 药的使用，城市公路、地铁、下水道的规划也得熟悉，同时还要用数学知识计算位置和时间等，要非常准确才行，车技也要一流。</summary><published>2011-03-22T05:32:00Z</published><updated>2011-03-22T05:32:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2011/03/22/1991325.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2011/03/22/1991325.html"/><content type="html">&lt;p&gt;之前看过一个电影，说的是抢运钞车，虽然是违法行为，这也是人家的工作。但这份工作的复杂度就太高了，不仅是黑客（侵入交通系统控制红绿灯），还得是建筑师、机械师、电焊工，以及各种枪 支 弹 药的使用，城市公路、地铁、下水道的规划也得熟悉，同时还要用数学知识计算位置和时间等，要非常准确才行，车技也要一流。&lt;/p&gt;&#xD;
&lt;p&gt;我们不那这种复杂的工作跟我们比较，就拿离我们比较近的，我们上学时都学过的，电子电路和单片机工程师，他们要完成一个工作需要装有电路板的试验箱，无数种芯片和电子元件，各种仪表设备（万用表、示波器和一些不知道叫什么名字的仪表），一台计算机用来写汇编和c代码，最后还要一张特大的桌子。&lt;/p&gt;&#xD;
&lt;p&gt;虽然知识复杂度上跟我们差不多，但如果他们有什么自己的想法，而公司又不支持他，那他几乎无法去实现自己的想法，因为家里没那么大的空间，也没钱买那么多的设备，呵呵。但作为开发人员的我们就只需要一台计算机而已，当然这种情况只发生在中国，因为我们用的软件可以全部都是盗版的，否则我们都要穷死不可。&lt;/p&gt;&#xD;
&lt;p&gt;最后来一张我养的金毛狗小时候照片，有码，呵呵！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1991325.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2011/03/22/1991325.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2011/03/11/1981679.html</id><title type="text">自我认识不清的开发者</title><summary type="text">在工作的几年里，我发现作为开发人员普遍存在自我认识不清的情况，出现这种情况的原因主要是不了解做为一个开发人员所应该具有的各种能力。在抛开计算机语言、数据结构及算法和操作系统网络数据库等层面的情况下（因为这些在具备兴趣这个要素时自然会主动的去学好），那么我认为做为开发人员所需要的要素...</summary><published>2011-03-11T09:39:00Z</published><updated>2011-03-11T09:39:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2011/03/11/1981679.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2011/03/11/1981679.html"/><content type="html">&lt;p&gt;在工作的几年里，我发现作为开发人员普遍存在自我认识不清的情况，出现这种情况的原因主要是不了解做为一个开发人员所应该具有的各种能力。在抛开计算机语言、数据结构及算法和操作系统网络数据库等层面的情况下（因为这些在具备兴趣这个要素时自然会主动的去学好），那么我认为做为开发人员所需要的要素：&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;&lt;strong&gt;兴趣；&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;理解能力；&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;学习能力。&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;以上是一些基本的要素，是能够把程序写好、解决问题的要素，但要想成为更高级的开发者，还需要：&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;&lt;strong&gt;成为一个有思想、会思考的人；&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;智商；&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;分析能力。&lt;/strong&gt;&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;如果你研究过PetShop，你可能可以模仿它并用到你们自己的项目里，可能做出来的东西也不错，但不代表你就是一个有思想、会思考的人，仅仅只能说是你的学习能力不错。&lt;/p&gt;&#xD;
&lt;p&gt;一个有思想、会思考的人往往是一个严格要求自己的人，还常常是一个懒惰的人，因为他不想去做重复的劳动，他总是想尽办法去让一切变的触手可及，确切说是一个有自己的思想、用自己方式思考的人，但现实中很多开发人员只会模仿。&lt;/p&gt;&#xD;
&lt;p&gt;因为这点这个世界才有了那么多了不起的企业，那么多了不起的语言、平台、框架，还有那么多了不起的软件以及了不起的人，等等。有了自己的思想后，智商和分析能力会让你能够实现你的思想。&lt;/p&gt;&#xD;
&lt;p&gt;如果还要加点什么要素的话，我想就是毅力、敢于表达和善于表达自己的思想。&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="font-size: 16px; line-height: 24px;"&gt;&lt;strong&gt;自我认识不清的开发者&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;可以这么说，很多做开发的根本不适合做开发，不少有两年以上开发经验的人，按理他应该比刚毕业没有开发经验的学生要有更多的能力，但事实是这两年他不仅把上学时学的数据结构等知识丢掉以外，他还没能把他现在工作中用的主打语言弄透，稍微复杂点的功能就实现不了，只知道使用现成的东西，更加糟糕的是这些年他没能在脑子里留下任何东西，对面向对象设计都没能掌握，却在纠结于设计上（包括架构）是用工厂模式好还是策略模式好。&lt;/p&gt;&#xD;
&lt;p&gt;开发软件是一个很辛苦的工作，客户愿意使用软件，当然是这个软件能够解决他们工作中的问题，而不是把他们的工作变的更繁琐，如何让软件操作起来更简单，这是一门学问，而不像我们平时遇到的增删改查这么简单。很多开发人员&amp;ldquo;一山望着一山高&amp;rdquo;，他发现别的公司的待遇比他现在获得的高，他就觉得他也应该获得更高的待遇，或者想跳槽，他不去想想同样做为开发者，个体的差异有多大，可能以他的能力目前仅仅只能做做增删改查的工作，而他却希望获得其他人做复杂工作所得到的待遇。&lt;/p&gt;&#xD;
&lt;p&gt;不过这也不是指所有人，有些刚毕业的学生有很强的能力和潜力，他完全达到了上面说的基本要素，而且他工作很积极，代码产生错误的可能性更小，甚至比有几年工作经验的同事更有能力并且做的更多的工作，而他获得的待遇相比之下很少，这个时候我很支持他为自己去争取更多或者跳槽。另外如果具有上面说的高级开发人员的能力，同时在目前的情况下无法获得更多，那么跳槽是最好的选择。&lt;/p&gt;&#xD;
&lt;p&gt;我很支持跳槽，跳槽是优化我们这个行业资源分配、让每个人在合适的企业和合适的岗位贡献他的能力的最好方式。&lt;/p&gt;&#xD;
&lt;p&gt;说完对开发人员的看法，以后要说下作为软件开发的企业和头头应该要具有的能力。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1981679.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2011/03/11/1981679.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/09/13/1825354.html</id><title type="text">知道挖掘机如何从货车上下来吗？</title><summary type="text">1往后开直到履带出车斗一半就停止（这里的“后”是相对与货车来说的，下面同样）；2将铲子放到地面支撑住；3继续往后开一点；4铲子放力使履带出车斗的那头着地；5铲子转180度支撑到车斗上；6继续往后开使履带的另一头悬空；7铲子放力使悬空那头的履带也着地；8整个履带都着地了想怎么开就怎么开吧。</summary><published>2010-09-13T15:39:00Z</published><updated>2010-09-13T15:39:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/09/13/1825354.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/09/13/1825354.html"/><content type="html">&lt;p&gt;有天下班，路上看到一辆货车载着一辆挖掘机（履带式，还有个长长手臂的那种），我看到挖掘机一直往后开，但货车并没有梯子，我很怀疑挖掘机能这样直接冲下去，所以就停下想看看挖掘机的司机是否有这个胆量，看后让我惊呆了，我现在把他下来的整个过程写下，很奇妙的技巧，呵呵。&lt;/p&gt;&#xD;
&lt;p&gt;1往后开直到履带出车斗一半就停止（这里的&amp;ldquo;后&amp;rdquo;是相对与货车来说的，下面同样）；&lt;/p&gt;&#xD;
&lt;p&gt;2将铲子放到地面支撑住；&lt;/p&gt;&#xD;
&lt;p&gt;3继续往后开一点；&lt;/p&gt;&#xD;
&lt;p&gt;4铲子放力使履带出车斗的那头着地；&lt;/p&gt;&#xD;
&lt;p&gt;5铲子转180度支撑到车斗上；&lt;/p&gt;&#xD;
&lt;p&gt;6继续往后开使履带的另一头悬空；&lt;/p&gt;&#xD;
&lt;p&gt;7铲子放力使悬空那头的履带也着地；&lt;/p&gt;&#xD;
&lt;p&gt;8整个履带都着地了想怎么开就怎么开吧。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1825354.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/09/13/1825354.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/08/15/1799853.html</id><title type="text">一次进销存软件架构的实践（二）——业务外观层设计</title><summary type="text">这里接着上次的文章说下业务外观层设计的结构和运行机制</summary><published>2010-08-14T17:20:00Z</published><updated>2010-08-14T17:20:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/08/15/1799853.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/08/15/1799853.html"/><content type="html">&lt;p&gt;&lt;a target="_blank" href="http://www.cnblogs.com/pains/archive/2010/07/23/1783411.html"&gt;一次进销存软件架构的实践（一）&amp;mdash;&amp;mdash;概述&lt;/a&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;1.结构&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;根据经验可以发现一个界面总是一块一块的，每一块里都是一些基本控件（按钮、文本框或者日期控件等）或者是一个网格控件和树形控件等，如果每块称为区域，里面的成为项，这样我们可以把界面抽象出两个基类：区域和项，从区域派生出的其他区域分别用来创建编辑区域、网格区域和树形区域，编辑区域中的项由项这个类中的类型属性通过分支语句去创建。&lt;/p&gt;&#xD;
&lt;p&gt;然后就是各种类型的窗体包含的区域不同，那就再加一个外观的类，它有个属性存放所有的区域，从外观派生出的类定义各种可能的区域。而各区域的位置等信息是由窗体去做的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" src="http://pic002.cnblogs.com/img/pains/201008/2010081500594066.jpg" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这些类还有其他的职责，从外观派生出的类负责各区域的交互等，区域负责数据绑定、固定的事件、数据初始化等，项也有数据绑定的职责，外观类的职责就是多很多了，主要一个职责是运行机制。&lt;/p&gt;&#xD;
&lt;p&gt;事实上我不是一开始就这样思考的，我是希望各种控件等都能够用统一的方式创建、绑定、验证和权限，所以才想到有基类抽象他们，才有了项，但单有项还不能完成一个复杂的界面，所以一步一步的思考就成上面描述的结构了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;2.运行机制&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这里简单列下运行时候要做的事。&lt;/p&gt;&#xD;
&lt;p&gt;1.预初始化&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;一些初始值的设置和合法性验证已决定是否继续等等必须放到窗体打开前的工作。&lt;/p&gt;&#xD;
&lt;p&gt;2.加载数据&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;通过外观类中的业务对象所实现的接口方法加载数据存储到外观类的dataset类型的数据属性中。&lt;/p&gt;&#xD;
&lt;p&gt;3.初始化权限&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;设置权限对象中一些与数据库中的数据有关的属性。&lt;/p&gt;&#xD;
&lt;p&gt;4.创建外观&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;这个时候窗体中的各控件就创建了。&lt;/p&gt;&#xD;
&lt;p&gt;5.初始化验证&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;同初始化权限，我的验证和权限用的是同样的一些类，我将他们抽象成了相同的东西。参考&lt;a target="_blank" href="http://www.cnblogs.com/pains/archive/2009/01/19/1378459.html"&gt;浅谈MIS系统架构&lt;/a&gt;，这块有些复杂但我不准备说了，用到了一个&lt;a target="_blank" href="http://www.codeproject.com/KB/cs/CSharpJavascriptEvalFunc.aspx"&gt;MB.JsEvaluator.dll&lt;/a&gt;来完成动态条件表达式。&lt;/p&gt;&#xD;
&lt;p&gt;6.结束初始化&lt;/p&gt;&#xD;
&lt;p&gt;7.绑定数据&lt;/p&gt;&#xD;
&lt;div id="AllanboltSignature"&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1799853.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/08/15/1799853.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/07/23/1783411.html</id><title type="text">一次进销存软件架构的实践（一）——概述</title><summary type="text">很高兴又一次开始谈软件的架构了，不过这个的探讨与09年初写的《浅谈MIS系统架构》不一样，之前是理论，现在是实践，而且这次在实际项目中把之前的理论都实现了，有过之而无不及，验证和权限、各层之间的低耦合、不再需要托控件，等等都实现了，其实一切能够实现得益于这次架构的魂——一切数据都会经过架构的程序</summary><published>2010-07-23T00:57:00Z</published><updated>2010-07-23T00:57:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/07/23/1783411.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/07/23/1783411.html"/><content type="html">&lt;p&gt;很高兴又一次开始谈软件的架构了，不过这个的探讨与09年初写的&lt;a href="http://www.cnblogs.com/pains/archive/2009/01/19/1378459.html" target="_blank"&gt;浅谈MIS系统架构&lt;/a&gt;不一样，之前是理论，现在是实践，而且这次在实际项目中把之前的理论都实现了，有过之而无不及，验证和权限、各层之间的低耦合、不再需要托控件，等等都实现了，其实一切能够实现得益于这次架构的魂&amp;mdash;&amp;mdash;一切数据都会经过架构的程序（我们有时叫底层，下面统一叫软件框架）。遗憾的是这次仍然是一个WinForm项目，如果是web开发那么其中的很多细节问题都需要从新思考，毕竟运行机制不同嘛。不过这个软件是一个非常成功的软件，而且实现了多语言、多单位和多币种等。&lt;/p&gt;&#xD;
&lt;p&gt;上面所说的各层之间的耦合、不再需要托控件等（其实还有很多）这些挺表面的东西可能大家并不以为然，那从架构的角度来看下这个问题。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1.这是一个什么样的架构，为什么要这样架构&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;之前看到高焕堂大师的《Android应用框架原理与程序开发》这本书，书的第二章《應用框架魅力的泉源：反向溝通》，当我第一眼看到&amp;ldquo;反向沟通&amp;rdquo;这个词，我感到作者是我的知音，当然，当我看完这章后我就成了作者的知音，因为作者把什么是&amp;ldquo;反向沟通&amp;rdquo;和为什么要&amp;ldquo;反向沟通&amp;rdquo;这个原理表达的很精准。&lt;/p&gt;&#xD;
&lt;p&gt;我常思考一个问题，那就是所谓的&amp;ldquo;三层架构&amp;rdquo;或者&amp;ldquo;多层架构&amp;rdquo;中如果实现表示层和业务层之间的低耦合，如果任由开发人员自己托控件，那么软件框架很难控制到它，虽然可以获得它，但在什么时候获得和这个控件是什么作用等都是软件框架无法决定的，无论是winform还是webform都是事件驱动式运行，开发人员会使用控件的那些事件和事件方法里写什么都是未知的，这样就可能会出现大量的代码冗余和层与层之间的高耦合，还有维护很不方便，同时这样也是一件浪费时间的工作。&lt;/p&gt;&#xD;
&lt;p&gt;要想解决这些问题，那首先就得让软件框架去完成大部分工作，当然是与实际业务无关的工作。如果我们有一个保存按钮，我希望当点击这个保存按钮时软件框架自动调用业务对象中的保存方法，而不需要实际业务窗体去添加事件和写调用的方法，这就出现了两个问题，一个是软件框架如何知道当前需要调用哪个业务对象中的保存方法，这个很简单，只要业务对象都有一个基类，然后实现各接口（如：ISavable），软件框架自己去调用相应接口方法；还有一个问题是要保存的数据在哪里？看来软件框架需要保持有数据实体的引用才行。&lt;/p&gt;&#xD;
&lt;p&gt;正如前面所说：一切数据（广义上的数据）都会经过软件框架。所以我的做法是：把需要用到对象都在软件框架的相应类里声明，像业务对象会在表示层的基类里声明，每一个窗体都有数据，这个数据也在表示层的基类里声明，等等（事实上在软件框架里声明的各属性很多，总共有十几个吧），开发人员需要给表示层基类的业务对象这个属性赋值，而数据则不需要去赋值，软件框架会自己去调用业务对象属性的查询数据的接口方法获得数据。&lt;/p&gt;&#xD;
&lt;p&gt;这样一来软件框架中还剩一个问题就是窗体上的控件如何在软件框架中声明？因为只有软件框架保持对窗体上控件的引用才可以用统一的方法进行数据绑定、可见和可用权限、验证以及它们所需要的事件，这就需要软件框架自己去创建控件，至于实际业务窗体显示哪些控件是由实际业务窗体向软件框架定制的（这个定制比较复杂，我把这块单独抽出来作为一个业务外观层，通过它能定制控件以及控件行为，后面会详细说它）。&lt;/p&gt;&#xD;
&lt;p&gt;可见：不再托控件不仅仅是目的还是实现这种架构思路的手段。&lt;/p&gt;&#xD;
&lt;p&gt;正因为一切数据（广义上的数据）都会经过软件框架，软件框架才能控制一切，&amp;ldquo;反向沟通&amp;rdquo;才能好好的工作。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;2.基本原理&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这里我将软件中会出现的窗体归了个类，每一种负责一种布局（窗体只负责布局，内部的控件等等由业务外观层去完成），比如带树的列表窗体（就是左边会显示一个树列表，右边一个Gridview的列表，树列表中的节点改变，Gridview列表的数据发生改变），这些窗体都继承自一个包含业务外观属性和一些方法的常用窗体类。实际业务窗体根据它的业务需要继承某一种布局的窗体，它还要使用业务外观层中的类创建窗体各个布局区域中的内容（很多控件），并给这些内容指定一个必选属性&amp;ldquo;字段名&amp;rdquo;（业务外观运行时会用这个&amp;ldquo;字段名&amp;rdquo;去绑定数据，并可以用这个&amp;ldquo;字段名&amp;rdquo;去索引到这个控件）和其他一些可选属性用来定制控件的内容、行为和样式等。&lt;/p&gt;&#xD;
&lt;p&gt;这样一来，业务外观层是重中之重，它负责界面的绘制、绝大部分交互的调度以及几乎所有的非功能需求（比如：刷新后焦点行定位问题）。下面是个草图，业务外观层简单的画了下（因为下一篇会着重讲它），为了简单说明问题，也只放了一个用于业务的接口ISelectable，事实上是有很多的，比如保存等，业务外观层依赖于所有的这些接口以完成界面的操作，而开发人员在写实际业务窗体代码中不需要主动调用业务对象或者接口。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" src="http://pic002.cnblogs.com/img/pains/201007/2010072308514381.jpg" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果换个角度去看，业务外观层不仅仅是上述作用，它是对平台（.NET）和组件的一层抽象，以另一种方式让开发人员编程，它还有它自己的运行机制。它还抛弃了以往拖拖拽拽操作麻烦、修改维护不方便（需要在设计器中设置，而现在可能只是移动上下行代码）、窗体风格不统一，同时它还屏蔽了第三方组件的使用（如果项目中用了第三方组件，但团队中不一定是每个人都很熟练的使用这套组件，那么这个方案能给大家节省很多时间）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;3.总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;常用窗体为各种布局的窗体的基窗体，它声明了业务外观属性，子类可以访问业务外观属性并设置自己的外观。&lt;/p&gt;&#xD;
&lt;p&gt;从常用窗体派生的窗体只负责布局，布局中的每一块称为区域，区域中的所有控件都是由业务外观层根据业务外观属性创建的。&lt;/p&gt;&#xD;
&lt;p&gt;业务外观层根据实际窗体中定制的操作创建事件和绑定对应的事件方法完成与业务对象的交互。&lt;/p&gt;&#xD;
&lt;p&gt;与业务对象的交互都是使用接口完成的，一个业务对象实现了某个接口就表示它拥有这样的能力，比如ISavable接口，就表示这个业务对象是可以保存的，所以我们定义了很多接口。&lt;/p&gt;&#xD;
&lt;p&gt;下一篇讲解释业务外观层的设计和权限与验证的设计。&lt;/p&gt;&#xD;
&lt;div id="AllanboltSignature"&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1783411.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/07/23/1783411.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/07/03/1770695.html</id><title type="text">斯蒂芬&amp;#183;霍金的宇宙和时间</title><summary type="text">我信口开河的说：公理1：万有引力越大时间过得越慢；定理1：速度越快时间过得越慢；推论1：不同星球上的时间不同；推论2：永远也无法达到光速，只能接近光速。</summary><published>2010-07-03T15:49:00Z</published><updated>2010-07-03T15:49:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/07/03/1770695.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/07/03/1770695.html"/><content type="html">&lt;div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;相信很多人都以为时间旅行是可行的，有这么一个有意思的实验验证回到从前，霍金写了很多份信分发到各地，邀请未来的人回到现在指定的时间参加他的party，呵呵，可是时间到的时候却没有人来参加，不过霍金说回到从前是不行的，因为如果可以回到从前，那有个疯狂的科学家回到了从前把自己枪杀了，就是说现在的科学家将不存在了，那是谁开的枪呢。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;不过霍金又说了不能回到从前但可以前往未来，今天就说这个，首先要说一个&amp;#8220;公理&amp;#8221;（注意了，这里和下面说的公理、定理、推论都是我自己定义的，科学上和霍金都没这样说）：&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;&lt;strong&gt;公理1：万有引力越大时间过得越慢。&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;这个是最难理解的，所以定义为公理，实在不能理解就强记住它吧，我也说不上来是怎么回事。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;因为上面的公理出现很多有意思的事情：楼下的钟走的比楼上的钟慢，所以你住楼下比楼上更加年轻，不过这个慢实在是慢的太少了；所有人造卫星上都有一个精准的钟，但这个钟总会比地球上的钟跑到快，所以需要它自动的调整时间差以跟地球上的时间一致，否则问题就大了；如果想前往未来，很好办，坐上一艘高科技的宇宙飞船，找一个黑洞，让飞船在正确的轨道上用正确的速度绕黑洞运行，5年后回到地球，对飞船上的人来说才过了5年，但地球上过了10年（要看情况），不过绕黑洞飞行很黄很暴力，千万不要模仿。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;&lt;strong&gt;推论1：不同星球上的时间不同。&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;因此不要做火星人，在地球人看来你会老的稍微快了一点点。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;&lt;strong&gt;定理1：速度越快时间过得越慢。&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;如果速度越快，那就是说正在绕一个高质量的天体飞行，也就相当于万有引力越大，那么时间自然也过得越慢（我瞎说的）。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;欧洲建成大型强子对撞机，如果把一个比较容易衰变的粒子放到这个对撞机中，让他加速到接近光速，再看这个粒子的衰变速度是不是比不加速时要慢，这个就可以也可以证明上面说的定理。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;如果能有汽车、火车、飞机或者飞船的速度可以接近光速，那就可以前往未来了。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;&lt;strong&gt;推论2：永远也无法达到光速，只能接近光速。&lt;br /&gt;&lt;span  style="font-weight: normal; "&gt;&lt;span  style="white-space: pre; "&gt;	&lt;/span&gt;如果达到光速时间将停止，如果超过光速时间将后退，就是回到从前了，但回到从前不可能。&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;也许要想达到光速那就必须改变形态，不能以具有质量的形式存在，而是化成能量（这个就更黄更暴力了，虽然只是点一把火的事情，但还是不要拿自己做实验了，让科学家去拿粒子做实验吧）；再也许整个宇宙的质量不足以让你绕它飞行达到光速。&lt;/div&gt;&lt;div&gt;&lt;span  style="white-space:pre"&gt;	&lt;/span&gt;以上所说纯属我个人信口开河，只为大家在这炎炎夏日达到防暑降温的效果，不过上面说的公理定理推论本身是有一定可信度的，不完全是我瞎说，我只是把难懂的东西总结了下，以方便感兴趣的可以简单通俗的理解。&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1770695.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/07/03/1770695.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/06/23/1763056.html</id><title type="text">AS3垃圾回收，在FlashPlayer10.1中实现回收Loader对象</title><summary type="text">这里做了一个demo，实现AS3垃圾回收，在FlashPlayer10.1中实现回收Loader对象</summary><published>2010-06-22T16:45:00Z</published><updated>2010-06-22T16:45:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/06/23/1763056.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/06/23/1763056.html"/><content type="html">&lt;div&gt;&lt;span style="white-space: pre;"&gt;	&lt;/span&gt;AS3和.NET一样，不需要开发人员关心垃圾回收，Player会在某个不确定的时间对没有被引用的对象进行内存释放，有时候需要垃圾回收器尽早工作，以释放占用的大量内存让程序顺利运行，所以网络上出现了叫做Hack的方法，如下：&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/ /&gt;&#xD;
&lt;br/ /&gt;&#xD;
Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;&#xD;
http://www.CodeHighlighter.com/&lt;br/ /&gt;&#xD;
&lt;br/ /&gt;&#xD;
--&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;GC():&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;LocalConnection().connect(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;foo&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;LocalConnection().connect(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;foo&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(error:Error)&amp;nbsp;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;trace("GC&amp;nbsp;OK!");&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&#xD;
}&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;但这个方法遇到要被回收的是Loader对象时就不太起作用了（注意有个&amp;ldquo;太&amp;rdquo;字，在下面的demo里还是起作用的），然后找到在cs4以上版本中的Loader对象有unloadAndStop()方法，这样我在Loader对象从舞台移除时就把它删得&amp;ldquo;干干净净&amp;rdquo;，并强制进行垃圾回收（调用上面的GC方法），代码如下：&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div onclick="cnblogs_code_show('5a280808-052a-4b05-9992-7137cf6676c2')" style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div id="cnblogs_code_open_5a280808-052a-4b05-9992-7137cf6676c2"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000;"&gt;pictLdr.addEventListener(Event.REMOVED_FROM_STAGE,remove);&lt;br /&gt;&#xD;
&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;remove(e:Event):&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&#xD;
{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pictLdr.removeEventListener(Event.REMOVED_FROM_STAGE,remove);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pictLdr.unloadAndStop();&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pictLdr.unload();&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pictLdr&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GC();&lt;br /&gt;&#xD;
}&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;下面的demo中放了一个按钮，点击加载并添加一个swf文件到舞台，这个swf的右上角有一个关闭按钮，用来把自己从舞台移除，我不断的来回点这两个按钮，测试结果显示内存不会一直增加，会保持在一个水平线上波动，有图有真相，下图就是测试时任务管理器中显示的内存占用：&lt;/div&gt;&#xD;
&lt;p&gt;&lt;img height="155" width="267" src="http://images.cnblogs.com/cnblogs_com/pains/as3GCLoader.JPG" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;附上demo，&lt;a target="_blank" href="http://files.cnblogs.com/pains/AS3GCLoader.rar" title="下载"&gt;下载&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个demo使用条件：&lt;/p&gt;&#xD;
&lt;p&gt;1.我是用cs5做的，所以请你用cs5打开；&lt;/p&gt;&#xD;
&lt;p&gt;2.播放器需要FlashPlayer10.1 r52，我是用这个测试成功的，试过用FlashPlayer10.0，不行；&lt;/p&gt;&#xD;
&lt;p&gt;3.请在beloaded.fla多放些图片什么的，放个10M左右吧，我上传上来的里面只有一张图（为了减少空间和流量，呵呵），太小了，无法看出内存变化情况。&lt;/p&gt;&#xD;
&lt;div id="AllanboltSignature"&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/pains/aggbug/1763056.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/06/23/1763056.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/pains/archive/2010/05/31/1748421.html</id><title type="text">C#读取U盘序列号</title><summary type="text">C#读取U盘序列号</summary><published>2010-05-31T09:51:00Z</published><updated>2010-05-31T09:51:00Z</updated><author><name>Rick Carter</name><uri>http://www.cnblogs.com/pains/</uri></author><link rel="alternate" href="http://www.cnblogs.com/pains/archive/2010/05/31/1748421.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/pains/archive/2010/05/31/1748421.html"/><content type="html">&lt;p&gt;代码从网上搜来，由于运行不成功，经自己修改过。&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;_serialNumber&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;List&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;();&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;调用这个函数将本机所有U盘序列号存储到_serialNumber中&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;matchDriveLetterWithSerial()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]&amp;nbsp;diskArray;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;driveNumber;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;searcher&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ManagementObjectSearcher(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SELECT&amp;nbsp;*&amp;nbsp;FROM&amp;nbsp;Win32_LogicalDiskToPartition&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ManagementObject&amp;nbsp;dm&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;searcher.Get())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;getValueInQuotes(dm[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Dependent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diskArray&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;getValueInQuotes(dm[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Antecedent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString()).Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;driveNumber&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;diskArray[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].Remove(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;span style="color: #000000;"&gt;).Trim();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;disks&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;ManagementObjectSearcher(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SELECT&amp;nbsp;*&amp;nbsp;FROM&amp;nbsp;Win32_DiskDrive&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(ManagementObject&amp;nbsp;disk&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;disks.Get())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(disk[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Name&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString()&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\\\.\\PHYSICALDRIVE&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;driveNumber)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;disk[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;InterfaceType&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString()&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;USB&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_serialNumber.Add(parseSerialFromDeviceID(disk[&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;PNPDeviceID&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString()));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;parseSerialFromDeviceID(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;deviceId)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;splitDeviceId&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;deviceId.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;\\&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;arrayLen&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;splitDeviceId.Length&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;serialArray&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;splitDeviceId[arrayLen].Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;serial&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;serialArray[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;serial;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;getValueInQuotes(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;inValue)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;posFoundStart&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;inValue.IndexOf(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\&lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #800000;"&gt;);&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;posFoundEnd&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;inValue.IndexOf(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\&lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&amp;nbsp;posFoundStart&amp;nbsp;+&amp;nbsp;1);&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;parsedValue&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;inValue.Substring(posFoundStart&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&amp;nbsp;(posFoundEnd&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;posFoundStart)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;parsedValue;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;img src="http://www.cnblogs.com/pains/aggbug/1748421.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/pains/archive/2010/05/31/1748421.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
