<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_一颗苹果</title><subtitle type="text">获得人生中的成功需要的专注与坚持不懈多过天才与机会|机会永远是给有准备的人|事业是需要一生时间去经营</subtitle><id>http://feed.cnblogs.com/blog/u/20427/rss</id><updated>2012-02-07T16:22:12Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/20427/rss"/><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html</id><title type="text">图模式的NoSQL数据库:Neo4j</title><summary type="text">Neo4J是什么？1. 一个高性能的图关系模型数据库2. 一个NoSQL的数据库3. 支持多种编程语言4. Neo4J擅长处理具有多关系的模型数据Neo4J中怎么删除与某个节点有关系的节点？1. 查找到目标节点所有关系2. 开启一个事务，删除所有关系的start node或end node3. 遍历所有找到的node并删除相关的RelationShip4. 然后删除node本身，提交事务 1 public static void DeleteRelativeNode(Node n) { 2 TraversalDescription td = Traversal.descript...</summary><published>2012-02-05T14:17:00Z</published><updated>2012-02-05T14:17:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html"/><content type="html">&lt;p&gt;&lt;span&gt;Neo4J是什么？&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div&gt;1. 一个高性能的图关系模型数据库&lt;/div&gt;&#xD;
&lt;div&gt;2. 一个NoSQL的数据库&lt;/div&gt;&#xD;
&lt;div&gt;3. 支持多种编程语言&lt;/div&gt;&#xD;
&lt;div&gt;4. Neo4J擅长处理具有多关系的模型数据&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;Neo4J中怎么删除与某个节点有关系的节点？&lt;/div&gt;&#xD;
&lt;div&gt;1. 查找到目标节点所有关系&lt;/div&gt;&#xD;
&lt;div&gt;2. 开启一个事务，删除所有关系的start node或end node&lt;/div&gt;&#xD;
&lt;div&gt;3. 遍历所有找到的node并删除相关的RelationShip&lt;/div&gt;&#xD;
&lt;div&gt;4. 然后删除node本身，提交事务&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;pre&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; DeleteRelativeNode(Node n) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;         TraversalDescription td = Traversal.description().relationships(Types.Relative, Direction.BOTH)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;                 .evaluator(Evaluators.excludeStartPosition());&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         Traverser t = td.traverse(n);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;(Node tn : t.nodes()) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt;             Iterable&amp;lt;Relationship&amp;gt; relationships = tn.getRelationships();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (Relationship r : relationships) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (r.getStartNode().equals(n) || r.getEndNode().equals(n)) {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;                     r.delete();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;                 }&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             }&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!tn.hasRelationship()) {&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;                 tn.delete();&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             }&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;     }&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
在Neo4j中删除节点的本身有一个条件，就是这个节点没有任何的关系存在。&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2339346.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/02/05/2339346.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html</id><title type="text">欲善其功，必先利其器--Nodejs调试技术总结</title><summary type="text">调试技术与开发技术构成了软件开发的基石。目前Nodejs作为新型的Web Server开发栈倍受开发者关注。总的来说Nodejs的应用程序主要有两部分：JavaScript编写的js模块和C语言编译的二进制模块。这里主要介绍三种avaScript模块的调试方法：基于Nodejs内建的调试器，基于V8调试插件和基于Chrome浏览器的调试器。以下所有的操作都将基于如下代码（example.js）：var http = require(&amp;#39;http&amp;#39;);var url = require(&amp;#39;url&amp;#39;);http.createServer(function (req, </summary><published>2012-01-15T13:35:00Z</published><updated>2012-01-15T13:35:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html"/><content type="html">&lt;p&gt;调试技术与开发技术构成了软件开发的基石。目前Nodejs作为新型的Web Server开发栈倍受开发者关注。总的来说Nodejs的应用程序主要有两部分：JavaScript编写的js模块和C语言编译的二进制模块。这里主要介绍三种avaScript模块的调试方法：基于Nodejs内建的调试器，基于V8调试插件和基于Chrome浏览器的调试器。以下所有的操作都将基于如下代码（example.js）：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; http = require('http');&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; url = require('url');&lt;br /&gt;http.createServer(&lt;span style="color: #0000ff;"&gt;function&lt;/span&gt; (req, res) {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = url.parse(req.url).pathname;&lt;br /&gt;        res.writeHead(200, {'Content-Type': 'text/plain'});&lt;br /&gt;        res.end(path);&lt;br /&gt;}).listen(1337, "127.0.0.1");&lt;br /&gt;console.log('Server running at http://127.0.0.1:1337/');&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;1. 基于Nodejs内建的调试器&lt;/p&gt;&#xD;
&lt;p&gt;Nodejs提供了一个内建调试器来帮助开发者调试应用程序。想要开启调试器我们需要在代码中加入debugger标签，当Nodejs执行到debugger标签时会自动暂停（debugger标签相当于在代码中开启一个断点）。代码如下：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = url.parse(req.url).pathname;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #0000ff;"&gt;debugger&lt;/span&gt;;&lt;/strong&gt;&lt;br /&gt;res.writeHead(200, {'Content-Type': 'text/plain'});&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;执行命令：node debug example.js 就可以进入调试模式。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011500104217.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在debug模式下，可以使用内建命令如repl去评估变量和表达式的值（如2所示）。我们也可以通过help命令来获取完整的调试命令列表。&lt;/p&gt;&#xD;
&lt;p&gt;Commands: run (r), cont (c), next (n), step (s), out (o), backtrace (bt), setBreakpoint (sb), clearBreakpoint (cb),&lt;br /&gt;watch, unwatch, watchers, repl, restart, kill, list, scripts, breakpoints, version&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;2. 基于V8插件的调试器&lt;br /&gt;Nodejs是基于google V8的引擎上构建的，Google为Eclipse提供了一个对应的调试插件。关于如何在Eclipse中安装和调试Nodejs程序就不再重复描述了，网上已经有很多的文章了（具体可以参考这篇文章http://cnodejs.org/blog/?p=911）。唯一要注意的是在默认情况下V8引擎支持的调试模式是本地模式。如果想要开启远程调试的话，我们需要修改Nodejs中的V8源文件：/deps/v8/src/platform-posix.cc&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;addr.sin_family = AF_INET;&lt;br /&gt;  addr.sin_addr.s_addr = htonl(&lt;span style="color: #ff0000;"&gt;INADDR_LOOPBACK&lt;/span&gt;); --&amp;gt; &lt;span style="color: #ff0000;"&gt;INADDR_ANY&lt;/span&gt;&lt;br /&gt;  addr.sin_port = htons(port);&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;然后重新编译Nodejs。&lt;/p&gt;&#xD;
&lt;p&gt;提示：&lt;/p&gt;&#xD;
&lt;p&gt;用插件来调试nodejs程序，你有时候会遇到什么connect refuse, get version failed等等错误。那么请注意你使用的ip的地址， 一般下127.0.0.1的回环地址是都工作的。如果你使用真实的ip地址，请检查防火墙设置。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;3. 基于Chrome浏览器的调试器&lt;/p&gt;&#xD;
&lt;p&gt;既然我们可以通过V8的调试插件来调试，那是否也可以借用Chrome浏览器的JavaScript调试器来调试呢？node-inspector模块提供了这样一种可能。我们需要先通过npm来安装node-inspector&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;npm install -g node-inspector &amp;nbsp;// -g 导入安装路径到环境变量&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;node-inspector是通过websocket方式来转向debug输入输出的。因此，我们在调试前要先启动node-inspector来监听Nodejs的debug调试端口。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011521054045.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;默认情况下node-inspector的端口是8080，可以通过参数--web-port=[port]来设置端口。在启动node-inpspector之后，我们可以通过--debug或--debug-brk来启动nodejs程序。通过在浏览器输入http://[ip address]:8080/debug?port=5858，我们会得到如下的调试窗口：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/16868/2012011521141853.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这三种方法各自有优缺点，我个人比较欣赏node-inspector的方式。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2322120.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/15/2322120.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html</id><title type="text">TDD中的一些问题</title><summary type="text">1. 我需要去测试get/set方法吗？这个问题一直是TDD中比较典型的一个问题。有两个观点，一个是不需要测试，因为get/set代码很简单，测试没有什么意义，除非是有特别的逻辑在里面。另一个观点是需要测，否则你的TDD就有缺陷。对于这个问题，我个人觉得需要这样看，第一，你提供get/set方法用途是什么，第二是你要怎么去测试它们。如果你的测试代码是这么写的：@Testpublic void testGetSetX() { setX(23); assertEquals(23, getX());}或者@Testpublic void testGetSetX() { x = 23...</summary><published>2012-01-08T03:56:00Z</published><updated>2012-01-08T03:56:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html"/><content type="html">&lt;p&gt;1. 我需要去测试get/set方法吗？&lt;/p&gt;&#xD;
&lt;p&gt;这个问题一直是TDD中比较典型的一个问题。有两个观点，一个是不需要测试，因为get/set代码很简单，测试没有什么意义，除非是有特别的逻辑在里面。另一个观点是需要测，否则你的TDD就有缺陷。对于这个问题，我个人觉得需要这样看，第一，你提供get/set方法用途是什么，第二是你要怎么去测试它们。如果你的测试代码是这么写的：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;@Test&#xD;
public void testGetSetX() {&#xD;
    setX(23);&#xD;
    assertEquals(23, getX());&#xD;
}&#xD;
或者&#xD;
@Test&#xD;
public void testGetSetX() {&#xD;
    x = 23;&#xD;
    assertEquals(23, x);&#xD;
}&#xD;
或者&#xD;
@Test&#xD;
public void testGetSetX() {&#xD;
    assertEquals(23, 23);&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;那么我觉得没有必要写这样的测试代码，因为这不是在测你自己的代码，而是在验证Java的编译器。但，如果是这样的代码&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;@Test&#xD;
public void testCreate() {&#xD;
    assertEquals(23, new MyClass(23).getX());&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;那么显然是有意义的，通常我们可以验证带参数的构造函数是否正确工作。 而对于set来说也是一样，&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;@Test&#xD;
public void testPrintMessage() {&#xD;
    MyClass mc = new MyClass();&#xD;
    mc.setX(23);&#xD;
    assertEquals("the x is 23", mc.printMessage());&#xD;
}&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这同时引出第二个问题&lt;/p&gt;&#xD;
&lt;p&gt;2. 什么才是真正意义上的TDD? TDD的T是test, D是driven, D是design. 这里test可以有多种解释: 单元测试, 业务逻辑测试,功能测试. 但我认为单元测试是比较符合含义的. 那么什么是单元测试? 很多人都不是真正的清楚. 就上面说的例子来看我可以为每一个函数添加测试, 那这样就是单元测试了吗? 不, 这不是单元测试. 这里指的单元是功能单元,而不是实现单元.一个类的每一个函数都可以称之为一个实现单元, 但一个实现单元并不一定是一个功能单元. 只有这个实现单元在业务逻辑上有单独的意义时,它才可称为功能单元(就上面的例子来说创建一个业务对象是一个功能单元), 也只有构建用于功能单元的测试才能称为单元测试. 之所以要以功能单元为最小测试单位是因为通常来说在软件开发过程中业务逻辑的变化频率要远少于实现逻辑的变化频率. 如果我们的测试构建于实现逻辑之上, 那么测试与实现是紧耦合的,我们就很难对实现进行重构或者优化(在项目的开发后期往往会陷入牵一发而动全身的情况). 而构建于功能单元之上的测试则不会有这样的缺陷.&lt;/p&gt;&#xD;
&lt;p&gt;3. 什么是Mock, Fake, Dummy? 在开发单元测试过程中,我们经常会听到Mock, Fake, Dummy的字样. 不过我想很少人会去注意它们之间的区别. 从字面意义上讲都是"假的"意思, 那么区别是什么? 首先是Mock, mock的含义是替换实现, 并加以验证. mock的通常的做法是构建一个伪接口来代替真实接口, 当程序调用到该接口时返回一个预置的对象(可以是真对象也可以是假对象). 最关键是我们要去验证该接口是否真的被调用. 所以我们通常可以看到一个verify操作在单元测试最后. Fake的含义是伪对象,就是构建一个假的对象来替换真实对象, Fake更倾向于数据实体. Dummy的含义是哑对象. 哑对象就是无意义的对象, 诸如null或是new object(对业务无价值的对象). 只起到一个占位的作用,而没有什么具体含义. 这里有篇文章很全面的阐释&lt;a href="http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html"&gt;相关的内容&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;总结一下,tdd是一个agile实践里面很重要的一个实践. 充分理解tdd的含义和目的将有助于更好的执行agile过程.&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2102388.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/08/2102388.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html</id><title type="text">参加hello radar回来</title><summary type="text">公司为了扩大大家的技术知识面，同时也对radar上的新技术进行一些探索，因此开始了hello radar系列session，这期的主题是nodejs。其实我在之前已经写过一些关于nodejs的文章。这回也算是总结一下这阶段的探索经历。nodejs无疑是目前互联网开发方面最热门的技术之一。究其原因一是其能够支持超高的并发连接（单服务器能做到&amp;gt;8000的并发量）,二是使用事件异步编程模式,三是采用了javascript作为服务器端编程语言. 这三个方面也正是目前大多数主流框架正在解决但未解决好的.对于目前的web服务器来说, 单服务器的连接并发量能到3000~5000已经非常不错了. 但这样</summary><published>2012-01-07T15:24:00Z</published><updated>2012-01-07T15:24:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html"/><content type="html">&lt;p&gt;公司为了扩大大家的技术知识面，同时也对radar上的新技术进行一些探索，因此开始了hello radar系列session，这期的主题是nodejs。其实我在之前已经写过一些关于nodejs的文章。这回也算是总结一下这阶段的探索经历。&lt;/p&gt;&#xD;
&lt;p&gt;nodejs无疑是目前互联网开发方面最热门的技术之一。究其原因一是其能够支持超高的并发连接（单服务器能做到&amp;gt;8000的并发量）,二是使用事件异步编程模式,三是采用了javascript作为服务器端编程语言. 这三个方面也正是目前大多数主流框架正在解决但未解决好的.对于目前的web服务器来说, 单服务器的连接并发量能到3000~5000已经非常不错了. 但这样的并发量对于当前具有海量用户的大型网站来说还是非常的少. 主要的原因是大多数web服务器对每一个request请求要么使用一个线程要么使用一个进程来处理,这也就是说在这个request返回之前线程或进程占用的资源是不会释放的.以每个线程占用2m的内存来说, 5000个并发就需要10g的内存(很恐怖吧). 我们来看一下nodejs是怎么解决这一问题的? 我们都知道nodejs是一个单线程单进程的服务器, 它对于request的请求并不使用线程去处理, 而采用了注册回调的方式. 也就是说对于request请求并不等到整个处理结束就释放连接去服务另一个请求.而处理过程被委托到后台线程(这里的线程与rquest的线程是不同的)中执行, 直到之前的处理结束再将数据发送回客户端.这样nodejs服务器就可以处理大量的并发连接.另外由于js天生对事件模型的支持并且拥有广大的开发群体, Ryan很自然就选择js作为nodejs的开发语言.&lt;/p&gt;&#xD;
&lt;p&gt;那么我们说任何的新技术都不能可能解决所有的问题,nodejs也一样. 假设我们现在有10000个并发请求, 每一个请求需要10s去完成.那么根据nodejs的机制,我们大概可以知道每秒钟需要返回10000块数据回客户端, 如果每块数据100k, 那么传输的数据量就达到1g, 并且会有90000个请求等待返回. 这时候网络的I/O就成为了服务器的瓶颈.从这里可以看出nodejs并不适合处理这样的情况. 根据Ryan自己描述每个request请求处理不超过5ms会有较好的性能.具体的文章可以看&lt;a href="http://four.livejournal.com/963421.html"&gt;这里&lt;/a&gt;.那么什么样的应用符合这样的要求呢? 我认为微博, 聊天室和某些mobile应用是适合的.&lt;/p&gt;&#xD;
&lt;p&gt;作为完整的开发栈, nodejs提供了良好的包管理程序npm (node package management), 还有版本管理程序nvm (nodejs version management). nodejs的发展速度是惊人的,到目前为止已经有6000+的模块被开发出来, 这也是nodejs的一大特色. 关于npm可以看&lt;a href="http://npmjs.org/"&gt;这里&lt;/a&gt;. 关于nvm可以看&lt;a href="https://github.com/creationix/nvm"&gt;这里&lt;/a&gt;. 同样api文档对于开发者来说也是极其重要的, nodejs.org也提供了比较完善的&lt;a href="http://nodejs.org/docs/latest/api/index.html"&gt;api文档&lt;/a&gt;.对于任何程序来说,调试永远是必须的.nodejs是基于google的v8引擎实现的,那么我们同样可以使用eclipse的v8调试插件来实现对nodejs的调试.关于如何调试nodejs可以看&lt;a href="https://github.com/joyent/node/wiki/Using-Eclipse-as-Node-Applications-Debugger"&gt;这里&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;nodejs是一项新技术,尽管其发展的很快,给我们带来了很多新的开发理念. 但还有些领域处于摸索阶段, 一个是如何测试nodejs程序,特别是单元测试; 二是持续构建的框架.对于一个完整的项目来说测试和持续构建是重要的两个环节.&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2316008.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/07/2316008.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html</id><title type="text">时间匆匆，又到回顾时 - 2011年的最后一小时</title><summary type="text">很快再过几分钟就是2012了，这个传说中的世界末年就在眼前；当然那只不是人们的臆想罢了，太阳在2012照常的会东升西落，人们也会照常的工作和生活。那么在这样的时间点上，我想每个人都应该仔细的思考和总结一下2011年里的得失。在翻看自己2011年的博客时，我发现今年的博客比去年少写了，而且关于技术探讨的没有以前那么多了。在查看一下未发表的博客，原来这些兄弟们都在这里，还真是对不住这些兄弟们。没关系，我会在2012年里把你们都show出来的。闭上眼睛，仔细回顾2011年所发生的人和事。原来变化还是很大的，工作，家庭和生活都发生了变化，尽管这种变化并没有在今年里完成，但是给我带来了期许，我希望这些新</summary><published>2011-12-31T16:07:00Z</published><updated>2011-12-31T16:07:00Z</updated><author><name>moonz-wu</name><uri>http://www.cnblogs.com/moonz-wu/</uri></author><link rel="alternate" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html"/><content type="html">&lt;p&gt;很快再过几分钟就是2012了，这个传说中的世界末年就在眼前；当然那只不是人们的臆想罢了，太阳在2012照常的会东升西落，人们也会照常的工作和生活。那么在这样的时间点上，我想每个人都应该仔细的思考和总结一下2011年里的得失。在翻看自己2011年的博客时，我发现今年的博客比去年少写了，而且关于技术探讨的没有以前那么多了。在查看一下未发表的博客，原来这些兄弟们都在这里，还真是对不住这些兄弟们。没关系，我会在2012年里把你们都show出来的。&lt;/p&gt;&#xD;
&lt;p&gt;闭上眼睛，仔细回顾2011年所发生的人和事。原来变化还是很大的，工作，家庭和生活都发生了变化，尽管这种变化并没有在今年里完成，但是给我带来了期许，我希望这些新的变化能在新的一年里一一完结，而我的人生也将开启一个新的篇章。作为一个技术工作者，今年的回顾还是从技术开始吧！&lt;/p&gt;&#xD;
&lt;p&gt;从技术上，我从企业级的开发逐渐的转向了互联网开发，其中还有一些移动互联网的技术；从传统的c/c++转向Java/C#，进而向Javascript等脚本语言前进。工作平台也从windows扩展到了android。我希望这种转变能对我的技术能力有所改变，以适应行业新的发展趋势。2011年的技术要点是移动互联网，这个名词随着android和ios被揣到了大多数人的口袋里。2012年的主题依然还是移动互联网，但是会有所变化那就是与云计算的结合会更紧密，同时开发门槛会进一步提高。而对于我来说，我希望新的一年里能在android平台和互联网技术上更进一步。行业的另一个方向是方法论和新思想，从TDD到BDD到DDD，敏捷开发还是不二的主题，国内的IT公司在这方面依然相对落后。不过我想敏捷的13个实践或多或少会改变国内公司目前的业务流程和产品质量。而对于我来说，在新的一年里我希望能掌握其中3个实践：CI、重构与持续反馈。&lt;/p&gt;&#xD;
&lt;p&gt;从生活上，2011年做了很多的铺垫，这些铺垫有些是之前计划了的，有些是意外的。但是也正是因为这些的铺垫，所以我对2012年有很大的憧憬。2012年对于我来说将会是一个忙碌的一年。&lt;/p&gt;&#xD;
&lt;p&gt;从思想上，这一年经历了很多斗争，有决绝，有彷徨，有失落也有激动。正是这些复杂的情绪和社会的各种影响，使的我思想上发生了变化。尽管有些依然没有找到答案，但是我有所收获，这个收获就是读书-读书使人明智。因此我希望能在新的一年里坚持读完12本经典的书。&lt;/p&gt;&#xD;
&lt;p&gt;在写这句话的时候已经是2012年了，总结了那么多其实只要一句话就可以表达现在的心情：前方依旧迷茫，唯有认准方向，并坚持走下去，才能成功。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/moonz-wu/aggbug/2309236.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/moonz-wu/archive/2012/01/01/2309236.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
