<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[服务器开发(Server Development)]]></title> 
<link>http://www.libing.net.cn/index.php</link> 
<description><![CDATA[服务器开发 UDP服务器开发 TCP服务器开发 游戏服务器开发 IOCP 服务器设计]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[服务器开发(Server Development)]]></copyright>
<item>
<link>http://www.libing.net.cn/read.php/1722.htm</link>
<title><![CDATA[A Good site on Audiologica,Mysql,Sockets]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[推荐网站]]></category>
<pubDate>Sat, 17 May 2008 12:45:57 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1722.htm</guid> 
<description>
<![CDATA[ 
	http://tangentsoft.net/
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1721.htm</link>
<title><![CDATA[从Second Life看经济以及市场[散杂]]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[我看经济]]></category>
<pubDate>Sat, 17 May 2008 08:21:39 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1721.htm</guid> 
<description>
<![CDATA[ 
	Linden,林登,很喜欢这个名字！正如其名字,第二人生！<br/><br/>虚拟社区经济实体越来越在真实社会的经济实体中占有很大比重，比如腾讯公司的虚拟货币还有其他相类似公司的虚拟币，而从第二人生中，那其实是一个国家，甚至一个世界，而对于国家来说，经济实体必须有国家的相应部门进行监管，监控，才可以有条不紊的正常运作，比如国与国之间金本位概念！<br/><br/>市场，之前在一些游戏中已经出现了广告宣传的手法，同样，虚拟社区里面会包含越来越多的真实社会中的事情。包括市场机制，对于虚拟社会来说，里面如果存在和真实社会的交叉点，比如通过虚拟物品同真实社会经济挂钩，就会激励虚拟市场机制的发展，通过国内的一些信息大致了解了<a href="http://secondlife.com" target="_blank">Second Life</a>的一些情况，很多东西让我惊叹，构想也好，理念也好，创新也好，都是一个模式，而将这些模式在社会经济实体中表示出来，就会产生市场，就会产生需求。经济的主题是分配有限资源，而虚拟社会里面很多资源也属于这个范畴，从我的认识中，这是一种革新，而且无论是虚拟的市场，还是现实的市场，未来的发展中，都将在社会实体中占领越来越大的比重。<br/><br/><br/>一点点浅薄的看法。
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1720.htm</link>
<title><![CDATA[这个人性被歪曲的社会,真是极度无语了]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的生活日志]]></category>
<pubDate>Sat, 17 May 2008 05:27:25 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1720.htm</guid> 
<description>
<![CDATA[ 
	两件问题：<br/><br/>1：捐款数额问题<br/>前面一篇文章已经提到过了，不想再多说，这些喷粪的愤青，能不能理智一点，让这些有名族感的人物太伤心了，看了姚明的事件，还有对海外的捐款的整个原委，大家不要对任何一个公众人物去带有个人感情色彩，甚至人云亦云的观点去看事物了好不好？大学生，研究生，都TM是什么？<br/><br/>当然能力越大，责任越大，我不否认，只是很多时候，要考虑一下别人的感受！<br/><br/>2：明星的伤心事件或者明星的一些举动<br/><br/>看了一些其他明星的事情，比如 芙蓉，李宇春等，对于我们自己来说，看到很多报道都会热泪盈眶，他们也是人，为什么他们的眼泪他们的举动就是炒作呢？<br/><br/>人性歪曲！不否认一些炒作成分的存在，但是在这个时期，大家理智一点吧，不要为这次灾区添乱了，做好自己事情，一份心，一份意。<br/><br/>补充：红十字会也证实了很多要求不公开姓名的捐款，他们的数额也很多不小的，大家不要再去评价这些公众人物了，企业了，等整个灾区事件结束，再来评判也不迟，还是那句话，做好自己的事情。<br/><br/><span style="color: #0000FF;">很多时候，我们更加应该的是一颗感恩的心去感谢所有捐款的人，而不是指点他们的多少！That's Enough!</span>
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/post/my-Spider.php</link>
<title><![CDATA[半夜突然想到将服务器集群模式应用到爬虫模式中]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的服务器设计]]></category>
<pubDate>Fri, 16 May 2008 01:44:55 +0000</pubDate> 
<guid>http://www.libing.net.cn/post/my-Spider.php</guid> 
<description>
<![CDATA[ 
	原本计划，对每个Spider采用单独配置文件方式启动，然后爬完后退出，经过晚上的思考，发现这个方案或许从长远的Project来说是更加适合的。而且这种设计的话，就可以有爬虫集群了，通过Socket同集群Server端交互，Server按照某个配置文件或者控制来分配任务，可以很好的解决抓重问题，DBAgent已经差不多了。<br/><br/>进度很快，设计思路大致如下<br/><br/>DB&nbsp;&nbsp;----->DBAgent&nbsp;&nbsp;-- Spider1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Spider2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-----------> SpiderArrangeServer<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;----->DBAgent&nbsp;&nbsp;-- Spider...<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- SpiderN<br/><br/><br/>SpiderN使用Socket同SpiderArrangeServer交互<br/><br/>DBAgent可以部署多个，<br/>核心数据库采用Master/Slave架构<br/><br/>已经完成工作：<br/><br/>DBAgent开发<br/>Spider1抓取端开发<br/>Spider1分析端开发<br/><br/>剩下工作：<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为Spider添加Socket同SpiderArrangeServer交互模块<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开发SpiderArrangeServer端 可以考虑 Select模式，夸张的话就用IOCP(Win下)或者干脆跨平台开发，也应该不是问题
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1718.htm</link>
<title><![CDATA[对明星以及企业捐款的一些看法]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的生活日志]]></category>
<pubDate>Thu, 15 May 2008 10:12:51 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1718.htm</guid> 
<description>
<![CDATA[ 
	在这个时候，很多人关注着谁谁谁捐了多少钱？少了？多了？怎么样怎么样！其实个人说几句话，对于捐款以及捐多少其实我觉得都仅仅是个人私事，不管多少，都是一个爱心，不管是什么人，他有多么好的背景，或者说有多少钱，他就必须拿出多少，是否可以换个角度来说这个问题。<br/><br/>1：对于有些明星他们的确有经济上的困难，我们不要以我们的角度去看人家要捐多少吧。<br/>2：既然是捐，就是自愿，我们其他人更没有什么资格去评点这些行为。<br/>3：爱心，难道是可以用数量表示的吗？如果是那样，我情愿不卷。当然我已经做了，说明我的心里爱心是没有数量的。<br/>4：在没有要求好自己的时候，请不要要求别人。有些艺人的捐款是私下里走的，他们并不想让人们知道这些行为，难道你们真的非要在面上刻个字，A是捐款英雄吗？大家考虑过另外一个问题吗？大家的圈子不一样，我打个比方，在单位募捐的时候，我捐了一部分钱，为什么说一部分呢，因为我不能捐太多了，否则其他人怎么办？我们国家就这种形式，不要逼别人，也不要比别人。但是同样我可以换个角度换个方式私下走账。而这个钱就不会给任何人带来压力，只有我自己心里知道，这是一个爱心，和那个爱心一样。他们也一样，如果某明星捐了N个0，和他差不多的明星怎么办？而这个明星本身并不像社会估计的那样有经济实力，所以为了考虑大家的感受，账面上他不能走太多的。希望大家理智一点的看待这个明星事情。当然我并不是替任何人说话，只是希望我们理智的看待这些问题，爱国，爱心是不能用数字来衡量的。<br/><br/><br/>一点点小小看法，也是我个人的观点。
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/post/php-1.php</link>
<title><![CDATA[The future of PHP]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的PHP专栏]]></category>
<pubDate>Thu, 15 May 2008 06:35:51 +0000</pubDate> 
<guid>http://www.libing.net.cn/post/php-1.php</guid> 
<description>
<![CDATA[ 
	<span style="color: #FF0000;">New PHP V6 features</span><br/><br/><span style="color: #0000FF;">PHP V6 is currently available as a developer snapshot, so you can download and try out many of the features and changes listed in this article. For features that have been implemented in the current snapshot, see Resources. </span><br/><br/><span style="color: #0000FF;">Improved Unicode support</span><br/><br/>Much improved for PHP V6 is support for Unicode strings in many of the core functions. This new feature has a big impact because it will allow PHP to support a broader set of characters for international support. So, if you're a developer or architect using a different language, such as the Java™ programming language, because it has better internationalization (i18n) support than PHP, it'll be time to take another look at PHP when the support improves. <br/><br/>Because you can download and use a developer's version of PHP V6 today, you will see some functions already supporting Unicode strings. For a list of functions that have been tested and verified to handle Unicode, see Resources. <br/> <br/><span style="color: #FF4500;">Namespaces</span><br/><br/>Namespaces are a way of avoiding name collisions between functions and classes without using prefixes in naming conventions that make the names of your methods and classes unreadable. So by using namespaces, you can have class names that someone else might use, but now you don't have to worry about running into any problems. Listing 1 provides an example of a namespace in PHP. <br/><br/>You won't have to update or change anything in your code because any PHP code you write that doesn't include namespaces will run just fine. Because the namespaces feature appears to be back-ported to V5.3 of PHP, when it becomes available, you can start to introduce namespaces into your own PHP applications. <br/><br/><br/>Listing 1. Example of a namespace<br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>// I'm not sure why I would implement my own XMLWriter, but at least<br/>// the name of this one won't collide with the one built in to PHP<br/>namespace NathanAGood;<br/>class XMLWriter <br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Implementation here...<br/>&#125;<br/><br/>$writer = new NathanAGood::XMLWriter();<br/><br/>?><br/>[/codes] <br/><br/><br/><span style="color: #FF0000;">Web 2.0 features</span><br/><br/>Depending on how you use PHP and what your scripts look like now, the language and syntax differences in PHP V6 may or may not affect you as much as the next features, which are those that directly allow you to introduce Web 2.0 features into your PHP application. <br/><br/><span style="color: #FF4500;">SOAP</span><br/><br/>SOAP is one of the protocols that Web services "speak" and is supported in quite a few other languages, such as the Java programming language and Microsoft® .NET. Although there are other ways to consume and expose Web services, such as Representational State Transfer (REST), SOAP remains a common way of allowing different platforms to have interoperability. In addition to SOAP modules in the PHP Extension and Application Repository (PEAR) library, a SOAP extension to PHP was introduced in V5. This extension wasn't enabled by default, so you have to enable the extension or hope your ISP did. In addition, PEAR packages are available that allow you to build SOAP clients and servers, such as the SOAP package. <br/><br/>Unless you change the default, the SOAP extension will be enabled for you in V6. These extensions provide an easy way to implement SOAP clients and SOAP servers, allowing you to build PHP applications that consume and provide Web services. <br/><br/>If SOAP extensions are on by default, that means you won't have to configure them in PHP. If you develop PHP applications and publish them to an ISP, you may need to check with your ISP to verify that SOAP extensions will be enabled for you when they upgrade. <br/><br/><span style="color: #FF0000;">XML</span><br/><br/>As of PHP V5.1, XMLReader and XMLWriter have been part of the core of PHP, which makes it easier for you to work with XML in your PHP applications. Like the SOAP extensions, this can be good news if you use SOAP or XML because PHP V6 will be a better fit for you than V4 out of the box. <br/><br/>The XMLWriter and XMLReader are stream-based object-oriented classes that allow you to read and write XML without having to worry about the XML details. <br/><br/><br/><span style="color: #FF0000;">Things removed</span><br/><br/>In addition to having new features, PHP V6 will not have some other functions and features that have been in previous versions. Most of these things, such as register_globals and safe_mode, are widely considered "broken" in current PHP, as they may expose security risks. In an effort to clean up PHP, the functions and features listed in the next section will be removed, or deprecated, from PHP. Opponents of this removal will most likely cite issues with existing scripts breaking after ISPs or enterprises upgrade to PHP V6, but proponents of this cleanup effort will be happy that the PHP team is sewing up some holes and providing a cleaner, safer implementation. <br/><br/>Features that will be removed from the PHP version include:<br/><br/>magic_quotes <br/>register_globals <br/>register_long_arrays <br/>safe_mode <br/>magic_quotes <br/><br/>Citing portability, performance, and inconvenience, the PHP documentation discourages the use of magic_quotes. It's so discouraged that it's being removed from PHP V6 altogether, so before upgrading to PHP V6, make sure that all your code avoids using magic_quotes. If you're using magic_quotes to escape strings for database calls, use your database implementation's parameterized queries, if they're supported. If not, use your database implementation's escape function, such as mysql_escape_string for MySQL or pg_escape_string for PostgreSQL. Listing 2 shows an example of magic_quotes use. <br/><br/><br/>Listing 2. Using magic_quotes (discouraged)<br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>// Assuming magic_quotes is on...<br/>$sql = "INSERT INTO USERS (USERNAME) VALUES $_GET['username']";<br/>?><br/>[/codes]<br/><br/><br/>After preparing your PHP code for the new versions of PHP, your code should look like that in Listing 3.<br/><br/><br/><span style="color: #FF0000;">Listing 3. Using parameterized queries (recommended)</span><br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>// Using the proper parameterized query method for MySQL, as an example<br/>$statement = $dbh->prepare("INSERT INTO USERS (USERNAME) VALUES ?");<br/>$statement->execute(array($_GET['username']));<br/>?><br/>[/codes] <br/><br/><br/>Now that support for magic_quotes will be completely removed, the get_magic_quotes_gpc() function will no longer be available. This may affect some of the older PHP scripts, so before updating, make sure you fix any locations in which this functions exists. <br/><br/><span style="color: #FF0000;">register_globals </span><br/><br/>The register_globals configuration key was already defaulted to off in PHP V4.2, which was controversial at the time. When register_globals is turned on, it was easy to use variables that could be injected with values from HTML forms. These variables don't really require initialization in your scripts, so it's easy to write scripts with gaping security holes. The register_globals documentation (see Resources) provides much more information about register_globals. See Listing 4 for an example of using register_globals. <br/><br/><br/><span style="color: #0000FF;">Listing 4. Using register_globals (discouraged)</span><br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/><?php<br/>// A security hole, because if register_globals is on, the value for user_authorized<br/>// can be set by a user sending them on the query string <br/>// (i.e., http://www.example.com/myscript.php?user_authorized=true)<br/>if ($user_authorized) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Show them everyone's sensitive data...<br/>&#125;<br/>?><br/>[/codes] <br/><br/><br/>If your PHP code uses global variables, you should update it. If you don't update your code to get prepared for newer versions of PHP, consider updating it for security reasons. When you're finished, your code should look like Listing 5. <br/><br/><br/>Listing 5. Being specific instead (recommended)<br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>function is_authorized() &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_SESSION['user'])) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&#125;<br/><br/>$user_authorized = is_authorized();<br/>?><br/>[/codes] <br/><br/><br/><span style="color: #FF0000;">register_long_arrays</span><br/><br/>The register_long_arrays setting, when turned on, registers the $HTTP_*_VARS predefined variables. If you're using the longer variables, update now to use the shorter variables. This setting was introduced in PHP V5 — presumably for backward-compatibility — and the PHP folks recommend turning it off for performance reasons. Listing 6 shows an example of register_long-arrays use. <br/><br/><br/>Listing 6. Using deprecated registered arrays (discouraged) <br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Echo's the name of the user value given on the query string, like<br/>&nbsp;&nbsp;&nbsp;&nbsp;// http://www.example.com/myscript.php?username=ngood<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo "Welcome, $HTTP_GET_VARS['username']!";<br/>?><br/>[/codes] <br/><br/><br/>If your PHP code looks like that shown in Listing 6, update it to look like that in Listing 7. Shut off the register_long_arrays setting if it's on and test your scripts again. <br/><br/><br/>Listing 7. Using $_GET (recommended)<br/>[codes=php]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><?php<br/>&nbsp;&nbsp;&nbsp;&nbsp;// Using the supported $_GET array instead.<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo "Welcome, $_GET['username']!";<br/>?><br/>[/codes] <br/><br/><br/><span style="color: #FF0000;">safe_mode</span> <br/><br/>The safe_mode configuration key, when turned on, ensures that the owner of a file being operated on matches the owner of the script that is executing. It was originally a way to attempt to handle security when operating in a shared server environment, like many ISPs would have. (For a link to a list of the functions affected by this safe_mode change, see Resources.) Your PHP code will be unaffected by this change, but it's good to be aware of it in case you're setting up PHP in the future or counting on safe_mode in your scripts. <br/><br/>PHP tags<br/><br/>Microsoft Active Server Pages (ASP)-style tags — the shorter version of the PHP tags — are no longer supported. To make sure this is not an issue for your scripts, verify that you aren't using the <% or %> tags in your PHP files. Replace them with <?php and ?>. <br/><br/><span style="color: #FF0000;">FreeType 1 and GD 1</span><br/><br/>The PHP team is removing support for both FreeType 1 and GD 1, citing the age and lack of ongoing developments of both libraries as the reason. Newer versions of both of these libraries are available that provide better functionality. For more information about FreeType and GD, see Resources. <br/><br/><span style="color: #FF0000;">ereg </span><br/><br/>The ereg extension, which supports Portable Operating System Interface (POSIX) regular expressions, is being removed from core PHP support. If you are using any of the POSIX regex functions, this change will affect you unless you include the ereg functionality. If you're using POSIX regex today, consider taking the time to update your regex functions to use the Perl-Compatible Regular Expression (PCRE) functions because they give you more features and perform better. Table 1 provides a list of the POSIX regex functions that will not be available after ereg is removed. Their PCRE replacements are also shown. <br/><br/><br/>Table 1. ereg() functions and their PCRE equivalents<br/>ereg() function Similar preg() function <br/>ereg(), eregi()&nbsp;&nbsp;preg_match()&nbsp;&nbsp;<br/>ereg_replace(), ereg_replacei()&nbsp;&nbsp;preg_replace()&nbsp;&nbsp;<br/><br/>Tags - <a href="http://www.libing.net.cn/go.php/tags/php/" rel="tag">php</a>
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1716.htm</link>
<title><![CDATA[[zh]在 windows IOCP 中，如何等待异步 IO 操作完成（包括被取消） 选项 ]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的服务器设计]]></category>
<pubDate>Thu, 15 May 2008 06:28:27 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1716.htm</guid> 
<description>
<![CDATA[ 
	依然是邮件列表的一篇文章，感觉讨论不错，摘录下来供大家欣赏一下。<br/>原文地址：http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e?hl=zh-CN<br/><br/>问题：<br/><span style="color: #FF0000;">Hi，all <br/>关于 IOCP 中如何安全释放资源，我想关键点是在于如何等待异步 IO 完成，被取消也暂且认为是一种完成。 <br/><br/>在使用多线程来运行 IOCP 的 GQCS 函数的时候，当某个一个线程（线程A）执行了 closesocket 之后，将引发在这个 socket 发出的所有异步 IO 被取消。 <br/>这些被取消的 IO 仍然会被 GQCS 取得并返回，并且通常这是在另外一个线程中（线程B）。 <br/><br/>一个可能的执行顺序如下： <br/>1.线程 A 执行了 closesocket <br/>2.线程 B 取得了一个被取消的 异步 IO 操作 <br/>3.线程 B 通过访问 PER_HANDLE_DATA 知道这是一个通过 closesocket 触发的 取消操作，因此简单地忽略 <br/>4.线程 A 释放 PER_HANDLE_DATA <br/><br/>上面的四个步骤，如果按顺序执行，那么就没有问题。 <br/>如果 步骤4 在 步骤2，或者3 之前执行，就会导致 线程B 访问已经被释放的内存。 <br/>如果有办法使得 线程A 等待 线程B 完成 步骤2和3 ，然后再进行 步骤4 ，这样就没有问题。 <br/><br/>查了 MSDN ，没有发现有实现这种等待功能的函数。不知道大家平时是怎么处理这个问题的？ <br/><br/>下面的 3 篇文章是讲关于 IOCP 中如何安全释放资源的，但可惜都没有提供完整的例子，很多细节的地方不知道是怎么实现的。 <br/><br/>http://blog.csdn.net/sodme/archive/2006/04/17/666062.aspx <br/>IOCP中的socket错误和资源释放处理方法 <br/><br/>http://blog.csdn.net/SeaWave/archive/2006/05/21/747863.aspx <br/>狗尾续貂：利用引用计数在多线程中安全释放资源 <br/><br/>http://libo.deng.blog.163.com/blog/static/40157422200772132422119/ <br/>编写大容量和健壮的服务器系列—处理IOCP资源释放 </span><br/><br/><br/><br/>Hi, all <br/><br/>最终采用了下面这篇文章种提到的做法 <br/><br/>>http://libo.deng.blog.163.com/blog/static/40157422200772132422119/ <br/>>编写大容量和健壮的服务器系列—处理IOCP资源释放&nbsp;&nbsp; <br/><br/>方式二 <br/>使用一个Hash表，对每个连接定义一个连接上下文，按socket值索引，把一些资源，例如信令缓存指针置于hash中的上下文。 <br/><br/>HANDLE CreateIoCompletionPort(HANDLE FileHandle, HANDLE ExistingCompletionPort, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads); <br/><br/>一个关键的地方是在把 client socket 关联到 完成端口，调用 CreateIoCompletionPort 的时候， <br/>CompletionKey 不要按常见的做法，把 PER_HANDLE_DATA 的指针传进行去，而是只把 client socket 按值传进去。 <br/>然后把 CompletionKey 和 PER_HANDLE_DATA 保存到一个 Hash 表中。 <br/>[codes=c]<br/>CreateIoCompletionPort： <br/><br/>ULONG_PTR completionKey = client; <br/>PER_HANDLE_DATA * perHandleData = GlobalAlloc(xxx); <br/>sessionManager->put( completionKey, perHandleData ); <br/>CreateIoCompletionPort( client, completionPort, completionKey, 0 ) <br/><br/><br/>GetQueuedCompletionStatus: <br/><br/>ULONG_PTR completionKey = 0; <br/>GetQueuedCompletionStatus( completionPort, &bytesTransferred, &completionKey, ... ); <br/>PER_HANDLE_DATA * perHandleData = sessionManager->get( completionKey ); <br/>if( NULL != perHandleData ) &#123; <br/><br/><br/>&#125; <br/><br/><br/>closesocket: <br/><br/>sessionManager->remove( completionKey ); <br/>closesocket( perHandleData->socket ); <br/>GlobalFree( perHandleData ); <br/><br/>[/codes]<br/><br/>>一个可能的执行顺序如下： <br/>>1.线程 A 执行了 closesocket <br/>>2.线程 B 取得了一个被取消的 异步 IO 操作 <br/>>3.线程 B 通过访问 PER_HANDLE_DATA 知道这是一个通过 closesocket 触发的 取消操作，因此简单地忽略 <br/>>4.线程 A 释放 PER_HANDLE_DATA <br/><br/><br/><span style="color: #0000FF;">重新回到这四个步骤，在 步骤1 中，在 closesocket 之前，先根据 completionKey 从 sessionManager 中删除掉 perHandleData 。 <br/>之后，在 线程B 中得到了 completionKey ，但是根据 completionKey 无法从 sessionManager 中找到 perHandlerData 。 <br/>这样，无论上面的四个步骤按什么顺序执行，都不会导致访问已经被释放内存。 </span><br/><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">Hi, all <br/><br/>刚好在这里看到了一个类似的想法 <br/><br/><br/>http://blog.codingnow.com/2007/07/robust.html#comment-12142 <br/><br/><br/>对大家的讨论不置可否，但是使用ID代替指针确实在某些方面是有益处的。 <br/>而某些时候我们无法使用智能指针。举个例子，完成端口中 <br/><br/><br/>GetQueuedCompletionStatus( <br/>*pTHIS, <br/>&dwNumberBytes, <br/>(PULONG_PTR)&lpKey, <br/>&lpEvent, <br/>INFINITE <br/>); <br/><br/><br/>其中的lpKey是一个非常关键的变量，我们一般把它置为一个对象的指针。这样我们就可以通过这个指针去访问该对象。 <br/><br/><br/>但是事实上很多时候这个指针的生命周期是不固定的，而由于其传入的是PULONG_PTR类型的值，我们又不能直接使用智能指针。要么就要繁琐的执行addre­f 和 release 这样的操作而完全丢失智能指针的优越性。 <br/><br/><br/>可是，如果这里传入的是一个ID或者HANDLE，为其对象的访问增加一层间接性。那么我们就可以预防非法的指针访问，从而达到安全的生命周期管理。 </div></div><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">个人感觉，使用引用计数还是hash，效果都差不多 <br/>hash表在这里，插入、删除、查找时都需要线程锁，不见得就比引用计数的InterlockedIncrement 和InterlockedDecrement开销小。 <br/>我目前是使用了hash id来作为后面逻辑层的通讯handle，在socket 的IOCP操作上，则使用了引用计数 <br/>在IOCP操作里，投递的OVERLAPPED结构（空闲列表重分配型分配器）、每连接的session（固定数量的对象池分配器，便于快速hash）都做了一­个封装 <br/>每次投递的生命期已一个OVERLAPPED结构release到0时结束，而一个连接，则以session的release到0为终结。 <br/>逻辑层的使用则类似 send(hash id , packet &)，与IOCP的工作线程隔离，不必关心连接无效导致的异常 </div></div><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">假设引用计数为 1 的时候，同时触发了两个事件，有两个线程同时持有了这个指针， <br/>又假设两个线程同时准备把计数减去一，然后就准备释放。 <br/><br/><br/>在做减法的时候，通过 InterlockedIncrement 这些方法可以保证不会有问题。 <br/>但是当一个线程释放了内存，而另外一个线程却正准备去访问这个计数器，检查计数器的值是不是 0 。 <br/>这种情况下，是不是就访问了已经被释放的内存？ </div></div><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">补一句，那个hash值，用int64，就可以基本保证唯一性了，例如我现在使用的 <br/><br/><br/>高8，每次分配出来时一个随机值（类似干扰码） <br/>次高24，对象池内坐标（一般应用来说这个量级足够了） <br/>低32，特征值（在session那里用了个接入人次数） <br/><br/><br/>这样，基本上不太可能出现重复的hash，而且寻址很快速 </div></div><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">汗，引用计数的作用，就是减到0时释放资源，自己这次减到0了，就是表示，除了自己没有任何使用者了，可以释放 </div></div><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">关于这里的引用计数，在详细一点说下 <br/>引用计数在这里，一次加减对，是以一次IO操作为单位，不是以某个线程持有为单位，例如 <br/>读请求投递 + <br/>读投递返回 - <br/>这里的加减，很可能在2个线程中完成，但是对于这次IO操作来说，是一个操作 <br/>同理，写请求，甚至是一个事件投递都可以看作一个加减单位，一次IO操作，基本上也就是一个OVERLAPPED的生命期。对于连接来说，在活跃列表中加了一个­引用，而在判定断开时减，其他的加减，全是IO操作 <br/>而资源的释放，通通在引用计数到0的那次release，也就是说，释放的控制权在被引用对象身上，这也是为什么OVERLAPPED和session都需要做­一次再封装的原因 </div></div><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">我之前的描述有问题，应该说是 <br/><br/><br/>假设引用计数为 2 的时候，同时触发了两个事件，有两个线程同时持有了这个指针， <br/>又假设两个线程同时准备把计数减去一，然后就准备释放。 <br/>在做减法的时候，通过 InterlockedIncrement 这些方法可以保证不会有问题。 <br/>假设把计数器递减为 0&nbsp;&nbsp;的线程先执行 free 操作， <br/>然后才是把计数器递减为 1&nbsp;&nbsp;的线程执行检查引用计数器是否为 0 。 <br/><br/><br/>这里的一个问题是，这个引用计数器是不是在 free 操作的范围呢？ <br/>如果在 free 的时候，把引用计数器也 free 掉了，那么后面这个线程的检查就会访问已经被释放的内存。 <br/><br/><br/>PS：所有用 OVERLAPPED 投递的异步操作，是否最后一定会被 GQCS 得到？ <br/>&nbsp;&nbsp;&nbsp;&nbsp;无论是正常完成操作，或者出现异常，或者被取消？ <br/>&nbsp;&nbsp;&nbsp;&nbsp;从 MSDN 的文档来看，特别是在提到取消操作的时候，常常看起来好像是不确定的。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;就是被取消的操作，不一定会被 GQCS 得到。不知道有没有哪份文档明确说明了这个问题？ <br/><br/><br/>如果被取消的操作有可能不被 GQCS 得到，也就是在静悄悄中就被取消了， <br/>那么就可能造成某一个计数器总是不为 0 ，导致长期占用资源。 </div></div><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">既然查了MSDN，就顺便看看InterlockedDecrement嘛，写的很清楚，The function returns the resulting decremented value. 也就是说往往用 <br/>if(0==InterlockedDecrement(&m_lRef)) <br/>OnDestroy(); <br/>至少在实际项目中，我还没有遇到这个地方出错的。 </div></div><br/><br/><br/><span style="color: #FF4500;">正确投递出去的请求，在实际项目中，我没有遇到没有返回的，但是注意投递时即错误的情况 </span><br/>[codes=c]<br/>pSession->AddRef(); <br/>pBuffer->AddRef(); <br/>pBuffer->SetOperation(Net_IO_Read_Completed); <br/>pBuffer->SetupRead(); <br/>pBuffer->SetUserPtr(pSession); <br/><br/><br/>DWORD dwNumBytes = 0; <br/>DWORD dwFlags = 0; <br/>CCriticalSection::COwner lock(pSession->GetCrit()); <br/>if(SOCKET_ERROR == ::WSARecv(pSession->m_hSocket,pBuffer->GetWSABUF(),1, &dwNumBytes,&dwFlags,pBuffer,NULL)) <br/>&#123; <br/>DWORD lastError = ::WSAGetLastError(); <br/>if(ERROR_IO_PENDING != lastError) <br/>&#123; <br/>pSession->ConnectionError(Net_ReadError,pBuffer,lastError); <br/>pSession->Release(); <br/>pBuffer->Release(); <br/><br/><br/><br/>&#125; <br/>&#125; <br/>[/codes]<br/><br/>至于怕引用计数无法正确到0，一般是代码逻辑问题，理清逻辑，这个也加减关系也就很清晰。 <br/><br/>对于socket IOCP，取消操作，基本只有closesocket导致，其他的不太可能去CancelIO，实际运行过程中，这个没返回的情况微乎其微 <br/>对于异常造成的，我一般是 <br/>[codes=c]<br/>try <br/>.... <br/>process <br/>.... <br/>catch() <br/>&#123; <br/>out_err <br/><br/><br/>&#125; <br/><br/><br/>->Release(); <br/>[/codes]<br/>这样即使中间处理过程异常，也一般能正确释放 <br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">从这些描述来看，使用 引用计数 看起来应该是没有问题的。 <br/><br/><br/>在使用 Hash 表的实现中，用 BoundsChecker 进行了检查，报了一些这样的错误： <br/>OutDbStr: HEAP[testiocpecho.exe]: <br/>OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed <br/><br/><br/>在 closesocket 的描述中提到： <br/>Thus, an application should not cleanup any resources (WSAOVERLAPPED structures, for example) <br/>referenced by the outstanding I/O requests until the I/O requests are indeed completed. <br/><br/><br/>看来像下面的这段代码是存在问题的。 <br/>sessionManager->remove( completionKey ); <br/>closesocket( perHandleData->socket ); <br/>GlobalFree( perHandleData ); <br/><br/><br/>如果还有未完成的异步操作在 IOCP 中，一旦 closesocket ，会导致 OS 往 OVERLAPPED 写一些信息。 <br/>如果 closesocket 之后，立即 free 掉 PER_HANDLE_DATA ，就会导致上面的错误。 <br/><br/><br/>之前一直困扰在如何等待所有这些异步 IO 操作完成（包括被取消），现在想到了一个办法。 <br/>IOCP 的内部实现是遵循 FIFO 的，在 closesocket 之后，不要立即 free ，而是重新 <br/>PostQueuedCompletionStatus 一个完成特殊事件给 GQCS ，通过 GQCS 得到这个事件，接着在进行 free 。 <br/><br/><br/>这样就相当于变相地等待所有这些异步 IO 完成了。 <br/>因为 closesocket 之后，所有 IO 都会被取消，这些取消的操作将在 GQCS 的队列中等待被处理， <br/>而用 PostQueuedCompletionStatus 投递的特殊事件，应该排在这些被取消的操作之后。 </div></div><br/><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">你想法不对，不能依赖于最后再Post一个IO出去，虽然IOCP是FIFO，但是不代表工作线程执行过程中也保证此次序（只有1个工作线程除外） <br/>一般通行做法，随时保持一个投递请求在IOCP上（一般是Read），closesocket时，此请求返回read到0 byte，可以判定session为break，这样移除额外保持的session引用（活跃列表所持有），其他各个投递在结束时，引用计数就到0了，那时即可­释放资源。 <br/>至于OVERLAPPED结构，每次IO操作的（请求-》结束）就是一块OVERLAPPED的生命期了，做个对象重用体系即可很好工作 </div></div><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">工作进程不是按顺序执行，这个说法是正确的。 <br/><br/><br/>我之前描述的做法，执行 closesocket 的线程已经把 PER_HANDLE_DATA 从 Hash <br/>表中删掉了，所以其他的线程从那一刻开始，就不可能再获得这个 PER_HANDLE_DATA <br/>的引用了。所以无论工作线程如何执行，只要其他线程不可能再获得这个 PER_HANDLE_DATA 的引用，就不会存在问题。 <br/><br/><br/>只是虽然工作线程不会访问 PER_HANDLE_DATA ，但是系统内核却可能会访问 OVERLAPPED ，而这个 OVERLAPPED&nbsp;&nbsp;正好在 <br/>PER_HANDLE_DATA 结构中，所以在 closesocket 之后，如果立即释放 PER_HANDLE_DATA&nbsp;&nbsp;就会有下面的错误 <br/>OutDbStr: HEAP: Free Heap block 123c1a0 modified at 123c1d4 after it was freed <br/><br/><br/>重新投递一个特殊事件，是指下面这样。昨天用了 BoundsChecker 进行了大压力的测试，没有再发现有内存访问错误了。 </div></div><br/><br/>[codes=c]<br/>void close( ... ) <br/>&#123; <br/>...... <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closesocket( ... ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset( &( iocpSession->mFreeEvent ), 0, sizeof( OVERLAPPED ) ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostQueuedCompletionStatus( eventArg->getCompletionPort(), 0, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SP_IocpEventCallback::eKeyFree, &( <br/>iocpSession->mFreeEvent ) ); <br/><br/><br/><br/>&#125; <br/><br/><br/>void eventLoop( .... ) <br/>&#123; <br/>...... <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL isSuccess = GetQueuedCompletionStatus( completionPort, <br/>&bytesTransferred, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&completionKey, &overlapped, INFINITE ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( eKeyFree == completionKey ) &#123; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert( NULL == iocpSession ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iocpSession = CONTAINING_RECORD( overlapped, <br/>SP_IocpSession_t, mFreeEvent ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete iocpSession->mSession; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free( iocpSession ); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return TRUE; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; <br/>...... <br/><br/><br/>&#125; <br/>[/codes]<br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">检查InterlockedIncrement的返回值而不是访问已经释放的内存，这个是安全的。</div></div><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">实际上， 还可以实现一种方法，不需要加引用计数的。 <br/>每个socket 在closesocket的时候，设置一个OnDestroy的标志位。 <br/>设置一个超时时间， 然后开一个单独的线程做这种dead socket的delete处理。 </div></div><br/><br/><br/><div class="quote"><div class="quote-title">引用</div><div class="quote-content">这个方法和我之前提到的做法类似，可以把这个 free 的动作放到 GQCS 线程去执行。 <br/>需要重新 PostQueuedCompletionStatus 方法投递一个特殊事件，使得 GQCS 能够得到这个事件，并作相应的处理。 <br/>这样就不需要一个特殊的线程。 </div></div><br/><br/>Tags - <a href="http://www.libing.net.cn/go.php/tags/%25E6%259C%258D%25E5%258A%25A1%25E5%2599%25A8/" rel="tag">服务器</a> , <a href="http://www.libing.net.cn/go.php/tags/iocp/" rel="tag">iocp</a>
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/post/iocp-wsasend-2.php</link>
<title><![CDATA[整理高性能网络编程邮件列表问题IOCP中WSASend的问题]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的服务器设计]]></category>
<pubDate>Thu, 15 May 2008 05:53:10 +0000</pubDate> 
<guid>http://www.libing.net.cn/post/iocp-wsasend-2.php</guid> 
<description>
<![CDATA[ 
	问题：<br/><br/><br/><span style="color: #FF0000;">在完成端口中，在向某个socket发送数据时，调用wsasend函数，假设我本次要发送的是1024字节的数据，调用wsasend返回实际发送的 <br/>字节数是小于1024时，是在立即在这里继续调用wsasend函数继续发送，还是在GetQueuedCompletionStatus函数里面来继 <br/>续发送？因为我要发送的数据，都是在重叠结构里，这里流程我还不是很清楚，望兄弟们解释一下 </span><br/><br/><br/><br/>回复：<br/><br/><span style="color: #800080;">1.首先,在重叠IO中,你说的问题应该不存在. <br/>&nbsp;&nbsp; WSASend发送后,要么数据都发送出去了.要么就返回WSA_IO_PENGING错误. <br/>2.如果你还是担心的话.那么你说的两个地方都可以发送 <br/>&nbsp;&nbsp; 但每发送一次,都要用不同的缓存区,并把没发送完的数据copy到新的缓存区,再发送 <br/>&nbsp;&nbsp;(在实际应用中,就是取一个新的PER_IO_DATA,也就是你说的包含WSAOVERLAPPED的那个数据结构)</span> <br/><br/><br/><span style="color: #0000FF;">补充：第二点非常重要，就是每发送一次，都需要使用不同的缓冲区，对于开发中，就是要新的Overlap结构，里面包含了一个HEvent句柄。</span><br/><br/><br/><br/>Tags - <a href="http://www.libing.net.cn/go.php/tags/%25E6%259C%258D%25E5%258A%25A1%25E5%2599%25A8/" rel="tag">服务器</a> , <a href="http://www.libing.net.cn/go.php/tags/iocp/" rel="tag">iocp</a> , <a href="http://www.libing.net.cn/go.php/tags/wsasend/" rel="tag">wsasend</a>
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1714.htm</link>
<title><![CDATA[我的团队]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的生活日志]]></category>
<pubDate>Wed, 14 May 2008 05:49:07 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1714.htm</guid> 
<description>
<![CDATA[ 
	突然心血来潮，想来说说我的团队，这些默默为社会创造价值的小伙子们。名字不分先后。<br/><br/>xixi,一个脑子充满了丰富的思维细胞的帅气单身小伙，很多时候，相识是一种缘分，很惊喜这种思维的人才，除了思维之外的就是技术了，如果一个好的构想用技术实现就是价值，就是产品，可以说你都具备了，而从实际来说，我们还缺少东西，或许说我还缺少东西，能让我们找到一个好的构想。相信，你毕业之后，你将成为一个不凡的将才。<br/><br/>dj,一个高高瘦瘦的刚刚告别单身的帅气小伙，无论从那个角度来说，你都很趋于完美，当然是我的角度来看的。为什么这么评价呢?想起很多次因为开发的问题或者思路的问题一起争吵，我觉得那是一种收获。技术，为人，处事，态度还有那年轻拼搏的心，无处无地不包含完美。相信以后的将来，你会有一番很好的作为，这些作为来自你对事情的态度。<br/><br/>fy,一个早就告别单身的帅气男生，称呼男生或许不太合适，但是那张娃娃脸，总是给人很亲切的感觉。秉性善良正值，而技术方面，说实在的，你们一届你可以算悟性最好的一个，但是换个角度，哥想提醒你一下，不要忘记了男人如果没有了事业，可能会一无所有，不知道我这么说会不会太过分，只是希望并祝福你可以看清楚一些事情，不要步胡哥的后尘。从根本来说，你将来会是某个行业的顶尖高手。<br/><br/>飞鸟,这个打球给人感觉很稳当的小伙，总是给人很踏实的感觉，跟哥快两年了，技术的进步就不多说了，因为哥信任你，校区这边这届，你是最棒的，当然，更多的时候，还需要再给你一些压力的锻炼，带项目的过程还应该让你再走一次，才能成熟起来。<br/><br/>天行健，人如其名，稳重的山东小伙子，勤快，认真，做事情也善于动脑子，只是最近有点找不到方向了，或许是感觉自己学的够多了，或许是觉得自己啥也不会，这是一个阶段，当你走过了，就能重新找到路，希望这天早点到来。Just do yourself.<br/><br/>Hansi,人才中的人才，可惜的是不够踏实，每天觉得这个好，想学这个，哪天心血来潮又换了，让哥感觉到一丝遗憾，不过从另外的角度，你的悟性以及智商会让你有一个好的归属，同时感情方面，不要强求，The one is waiting 4 u.<br/><br/>寻找你，其实说实在的，你并不适合做开发，但是你很适合去负责做一件其他的事情，你做事情的认真性，超过了我对所有人的期望，还有，多次帮哥处理的比较重要的事情，都非常顺利，说心里话，好好准备剩下的一段时间，把研究生考上，然后和你的女友together.<br/><br/>蜘蛛侠，一个很意外的人，意外在当初入团队的时候，是我最不看好的，而如今成了这届里面我最看好的，哥总夸自己眼睛好，这次可以算是失明了。这个年级，可以自己带领下面团队完成真实项目，产生经济效益，很难得，想起自己当年，甚至感觉惭愧。不管如何，N年后，你会比哥强的，Just belive yourself.<br/><br/>壮志凌云，怎么说呢，团队里面福建的人很多，而福建的人大都给人感觉聪慧，你也一样，只是你学习太好了，哥不得不让你少来团队参与开发，希望当你报送之后，可以继续和我们一起。<br/><br/>feifei,一个很棒的小伙，想起自己大二的时候，还在懵懵懂懂的看课本，或许是团队熏陶，或许是其他，已经懂得自己去欣赏品味优秀国内外论文，同样和壮志凌云一样，你的学习让哥希望你好好保证学习，两年后我们再来。<br/><br/>kitty,一个乖乖女生，善解人意，帮哥策划一些方案，前期负责国外外包频道的项目洽淡，后期主要负责团队的管理事务，你的那份爱心会感染团队每个人。<br/><br/>eiji,一个让所有学长以及我汗颜的女生，对程序的悟性超过了所有的前辈，大一的她已经参与两个重要项目，并在两个项目中基本占主导开发地位，在项目策划过程中，其犀利的思维，对程序思想的把握，对大局的感觉，足矣让我们这些做过几年开发的人感到惭愧，这些话并不是夸奖，只是纪实。希望哥可以让你尽快转型，学习一下更深层的技术，而非语言层面。<br/><br/>熙熙，对技术很执着的帅气男生，和eiji一起，是这一届中很不错的人才，多次想离开机械学院，投入妓院，让我无语，其实开发是无界的，好好学，one day,you will be success.<br/><br/>yangfei,帅气的男生，不知为何，我很注重第一感觉，这个小伙给我的第一感觉就是适合开发，而且很适合在我的团队中发展，所以留下你来，而在这些次的培养中，也证明我没有看错。<br/><br/>zhengkai,我的小小老乡，呵呵，其实希望你做开发的，可是你走是美工，不过没有关系，你的专业可能和你的决定有共同点，几次的开发让我觉得你不差于hansi这个家伙。慢慢的，你会成为团队的主力的，I believe.<br/><br/>shenzl,一个乖乖可爱小女生，说实在的，给人的第一感觉很奇怪，如果说似曾相识，大家肯定说我老套，不过说实在的，给人的那种感觉很奇怪，心很细腻，做什么都很认真，希望你可以好好掌握flash的action script，one day,one dream.<br/><br/>licy,一个和kitty很像的小女生，参与学校项目的美工，做的很棒。继续努力。<br/><br/>lini, 认知感很强的一个女孩，她？<br/><br/>张淼，很有市场感的一个男生，不过从另外的角度，你并不适合开发，或许需要你自己好好想清楚吧。不管如何，人都应该朝着最适合自己的方向发展，哥并不要求你什么，好好努力，做好自己。<br/><br/>果实，一句 收获自己 丰硕的果实，让人感觉蛮有意思的，可惜当时团队演说的时候，好像听懂的人不多。可惜了。<br/><br/>qixin,蜘蛛侠看重的男生，好好努力哦，时间是最重要的证明。<br/><br/>gzl,感觉有点太优秀了而并不适合团队的感觉，或许是团队不适合你，不管如何，继续走自己的路，有一天你会有成绩的。<br/><br/>最后就是 大家称呼的大叔了，哎，怎么说呢，批评一下吧，不够勤快，不过最近有项目压上来，应该会有所改善吧。继续努力了。<br/><br/>当然还有一些其他队员，由于印象中并没有一个切实的评价，所以暂时不敢多猜测，希望多加了解后，我可以补上。<br/><br/><br/>一点点小小看法。
]]>
</description>
</item><item>
<link>http://www.libing.net.cn/read.php/1713.htm</link>
<title><![CDATA[修改模型成功，效率提高很多]]></title> 
<author>huzhangyou2002 &lt;huzhangyou2002@gmail.com&gt;</author>
<category><![CDATA[信仰的程序人生]]></category>
<pubDate>Wed, 14 May 2008 04:57:19 +0000</pubDate> 
<guid>http://www.libing.net.cn/read.php/1713.htm</guid> 
<description>
<![CDATA[ 
	模型在分析的时候瓶颈总是很明显，经过分析处理，终于确定新的模型，代码改进之后，发现提高了非常多的效率，速度是原来的20+倍以上。而且量越多越明显。<br/><br/>开发对自己来说，已经不是很有兴趣了，什么语言并不是最重要的，重要的是理论模型的确定。给客户的方案中，越来越抛开了语言，而是设计以及架构，而从和客户的交流中，也越来越让客户找到自己的感觉，有种很自然的感觉。<br/><br/>或许是炫耀，或许是自满，抑或是找到自己感觉吧。
]]>
</description>
</item>
</channel>
</rss>