﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-dead-horse</title><link>http://www.cppblog.com/dead-horse/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 14 Apr 2026 23:09:02 GMT</lastBuildDate><pubDate>Tue, 14 Apr 2026 23:09:02 GMT</pubDate><ttl>60</ttl><item><title>linux命令、参数使用记录</title><link>http://www.cppblog.com/dead-horse/archive/2011/11/26/161008.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Sat, 26 Nov 2011 13:05:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/11/26/161008.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/161008.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/11/26/161008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/161008.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/161008.html</trackback:ping><description><![CDATA[<div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">curl</span><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">command line url</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">curl www.baidu.com &nbsp; &nbsp;查看网页源码</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">curl -o 【文件名】&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp; 保存网页，跟wget一样</span></div><div></div><div>curl -L&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp;如果网址是自动跳转的，这样就会跳转到新的网页</div><div></div><div>curl -i&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp;显示网页头信息和网页源代码</div><div></div><div>curl -I&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp;只显示网页头信息</div><div></div><div>curl -v&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp;显示整个http通信过程</div><div></div><div>curl&nbsp;<a href="http://www.baidu.com/?q=test">www.baidu.com?q=test</a>&nbsp;get表单提交</div><div></div><div>curl --data "q=test"&nbsp;<a href="http://www.baidu.com/">www.baidu.com</a>&nbsp;post表单提交</div><div></div><div><p style="font-family: arial, sans-serif; font-size: 13px; line-height: normal; background-color: #ffffff; ">假定文件上传的表单是下面这样：</p><blockquote style="font-family: arial, sans-serif; font-size: 13px; line-height: normal; background-color: #ffffff; "><p>　　&lt;form method="POST" enctype='multipart/form-data' action="upload.cgi"&gt;<br /> 　　　　&lt;input type=file name=upload&gt;<br /> 　　　　&lt;input type=submit name=press value="OK"&gt;<br /> 　　&lt;/form&gt;</p></blockquote><div>你可以用curl这样上传文件：</div></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><span style="font-family: arial, sans-serif; font-size: 13px;">　　curl --form upload=@localfilename --form press=OK [URL]</span></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><span style="font-family: arial, sans-serif; font-size: 13px;"><br /></span></span></div><div>curl --referer http://www.example.com&nbsp;<a href="http://www.example.com/">http://www.example.com</a>&nbsp;表示从哪里跳转过来</div><div></div><div>curl --user-agent "[User Agent]" [URL] 模拟user agent</div><div></div><div>curl --user-agent "[User Agent]" [URL] 发送cookie</div><div></div><div>curl --user-agent "[User Agent]" [URL] 增加头</div><div></div><div>curl --user-agent "[User Agent]" [URL] http认证</div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">tar</span><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">tar -xvf 解压</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">tar -cf target.tar.gz xxx压缩</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">tar -tvf target.tar.gz 查看压缩文件内容</span></div><br /><br /><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">PATH</span><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">path是命令行命令的选取路径。可以通过echo $PATH来查看。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">有时候需要修改路径，则通过export PATH /usr/bin:/bin 来修改。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">如果需要一直修改，则需要修改配置文件。在~/目录下有个.bash_profile文件，修改里面的PATH。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">修改完成后运行source ~/.bash_profile刷新。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">如果需要修改全局的，则可以修改/etc/profile。</span></div></div><br /><br /><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">chown 可以修改文件的拥有者</span><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">要拥有root权限才可以进行修改</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">chown [-cfhvR] [--help] [--version] user[:group] file..</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">最常用的参数是-R，当前目录下所有文件和目录进行变更（递归进行）</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">chown -R admin:admins * &nbsp; &nbsp;<a>//对当前目录下的所有文件权限变更为用户：admin</a>&nbsp;组admins</span></div></div></div></div><img src ="http://www.cppblog.com/dead-horse/aggbug/161008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-11-26 21:05 <a href="http://www.cppblog.com/dead-horse/archive/2011/11/26/161008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nodejs模块connect源码分析</title><link>http://www.cppblog.com/dead-horse/archive/2011/11/26/161007.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Sat, 26 Nov 2011 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/11/26/161007.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/161007.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/11/26/161007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/161007.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/161007.html</trackback:ping><description><![CDATA[<div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">connect是一个web server中间件。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">使用方法：</span></div><div><p>&nbsp;</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">var</span>&nbsp;connect&nbsp;=&nbsp;require('connect');<br />connect(<br />connect.static(__dirname&nbsp;+&nbsp;'/public',&nbsp;{&nbsp;maxAge:&nbsp;0&nbsp;})<br />,&nbsp;<span style="color: #0000FF; ">function</span>(req,&nbsp;res)&nbsp;{<br />res.setHeader('Content-Type',&nbsp;'text/html');<br />res.end('&lt;img&nbsp;src="/tobi.jpeg"&nbsp;/&gt;')<br />}<br />).listen(3000);</div><p>&nbsp;</p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">思路：</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">通过connect创建一个http|https server，提供http server的所有功能。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">connect是原型继承于http server的，它会用use到的中间件替换掉server的requestListener。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">通过connect.use(route, handle)来对每一个路由添加中间件，这些中间件handle会与route绑定保存在一个stack里面，每次有request请求的时候，遍历这个堆，找到对应route的handle，执行handle，如果handle最后调用了next(),就会继续寻找并执行下一个匹配的handle。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">通过封装handle，可以很容易的在connect基础上添加更多的middleware。</span></p><p>&nbsp;</p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">connect.js</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">有一个createServer方法，可以通过connect()访问到。根据第一个参数，如果是object，就当作是https的选项，创建HTTPSServer，如果第一个参数不是object，则创建HTTPServer，所有的参数（除了https的选项）都是一个中间件handle，会在HTTPServer绑定到&#8216;/&#8217;路径上。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">HTTPSServer是在HTTPServer的基础上添加了一层，可以启用HTTPS服务。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">同时，connect.js会读取middleware文件夹，把里面的中间件读取到，为他们创建getter,可以通过connect.static()访问到。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">而每一个中间件文件暴露在外的函数都是返回一个handle。</span></p><p>&nbsp;</p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">http.js</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">HTTPServer：初始化的时候会把所有的参数当作handle存放进stack，然后以handle方法为requestListener调用http.Server方法。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">HTTPServer随后会继承http.Server的原型。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">use(route, handle)</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">把handle去除外壳之后绑定到route上面，存入stack中。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">handle(req, res, next)</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">遍历整个stack，寻找到req.url与route匹配的元素，执行它的handle。当所有的元素都遍历完还有错误，则输出。</span></p><p>&nbsp;</p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">util.js</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">这是一个工具包，里面包含了用到的各种工具函数。</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">pause(obj)</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">把传递进来的obj对象的'data'和'end&#8216;事件都保存下来，返回两个函数：end()：不再保存事件。resume()：停止保存并把之前保存的事件释放出去给obj再次捕获，达到暂停这个obj对象的效果。（感觉可能会有bug,如果在这里释放的时候又有'data'或者'end'事件触发会不会导致顺序变乱？）</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">parseCookie(str)</span></p><p><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">把str以;或者，为分隔符分开。每一个都是一个cookie键值对，然后再以=分开。去除value的引号。每个键只能被取得一次。<br /><br />中间件:<br /><br />router<br /></span></p><div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">connect的route使用方法和express类似。</span></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">1</span>&nbsp;connect(connect.route(<span style="color: #0000FF; ">function</span>(app){<br /><span style="color: #008080; ">2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.get('/:id',&nbsp;middle1,&nbsp;middle2,&nbsp;cb);<br /><span style="color: #008080; ">3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.post('/admin',&nbsp;cbpost);<br /><span style="color: #008080; ">4</span>&nbsp;}));</div></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br clear="none" /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">route.js内有一个_methods数组，存放所有的route请求方法名称。（get/post/put/...）。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">methods对象和routes对象根据_methods内的名称，包含着响应的元素，如：methods['get'], routes['get']。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">methods对象，根据_methods数组内的方法名称，为每一个方法调用来一个生产函数，这个函数首先把routes对象内的成员赋值[]，然后返回一个函数，这个函数用来产生routes的内容。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">methods还有一个元素param,调用它可以为path中出现了某个param的时候设置对应的处理方法。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">例如：</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">app.param('id', function(req, res, next, val){})，</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">当path中有param id出现的时候，会先调用这个注册的函数再进行后面的操作。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">在进行完上述对象的初始化之后，route模块会进行fn.call(this, methods)的调用,即用methods作为参数调用传递进来的匿名函数。所以在app.get('/:id', cb, cb1);的时候，实际调用的是methods.get('/:id', cb, cb1)，而methods.get即是之前生产函数的返回函数。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">这个函数的处理：cb为这条路由的handle，middle1..middle2..等中间件函数将会存放在cb.middleware数组中(这里会产生一个bug)。然后把'/'转化成为正则对象，然后在转化正则的时候，可能会遇到路径里面有:id等key，会把这些key存放到keys里面。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">最终的routes内将会多处一条routes['GET']的记录：</span></div><div><p>&nbsp;</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->GET:<br />[&nbsp;{&nbsp;fn:&nbsp;[Object],<br />path:&nbsp;/^\/(?:([^\/]+?))\/?$/i,<br />keys:&nbsp;[Object],<br />orig:&nbsp;'/:id',<br />method:&nbsp;'GET'&nbsp;}&nbsp;]</div><p>&nbsp;</p><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">刚才说会产生一个bug，是当有两条以上的route以cb作为handle的时候：</span></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->app.get('/:id',&nbsp;middle1,&nbsp;middle2,&nbsp;cb);<br />app.get('/:id/test',&nbsp;middle3,&nbsp;cb);</div></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">因为最终的handle都是cb，此时cb的middleware数组会在第二次处理get的时候把第一次的覆盖掉，造成第一次的middleware被替换。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">至此，所有的准备工作完成了，然后会返回一个router函数作为handle。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">实际request请求触发的时候：</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">作为handle的router函数被调用，先通过match(req, routes, i)函数，查找req.method对应方法的route的path，与req.pathName匹配。找到路径匹配的把这个route内的这个对象内的fn，同时把keys params method存放到fn里面整合称为一个route返回。返回的route内容形式为</span></div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->{&nbsp;[Function]<br />&nbsp;&nbsp;middleware:&nbsp;[&nbsp;[Function],&nbsp;[Function]&nbsp;],<br />&nbsp;&nbsp;keys:&nbsp;[&nbsp;'id'&nbsp;],<br />&nbsp;&nbsp;method:&nbsp;'GET',<br />&nbsp;&nbsp;params:&nbsp;[&nbsp;id:&nbsp;'ca'&nbsp;]&nbsp;}</div></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">然后函数去寻找是否通过methods.param定义了这条route中的param的处理函数，如果有，在这里就执行完对应param的处理函数。之后执行middleware数组内的函数，最后执行这个route。即上一段中说到的fn。这之中能够链式执行下去的条件是中间函数都执行了next()，继续调用下去，当然也可以其中某个函数就结束整个处理。<br /><br />bodyParser<br /><br /><div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">bodyParser用来解析post方法传递过来的参数。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">只接受mime类型为</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">application/x-www-form-urlencoded</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">application/json</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">multipart/form-data</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">三种的非GET和HEAD请求。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><br clear="none" /></span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">application/x-www-form-urlencoded通过模块qs.parse来解析。</span><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">application/json通过JSON.parse解析。</span></div><div><span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; ">multipart/form-data是文件上传，通过formidable解析。<br /><br /><br />static<br /><div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">static是一个静态文件服务器。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">connect.static(root, options)会产生一个handle，handle设置默认的options然后调用send函数。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br clear="none" /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">options内容：</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">root:静态服务器的根路径，必须由connect.static传入。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">path:访问的文件路径</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">getOnly:访问方法限制（默认是true：只允许get方法访问&nbsp;）</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">maxAge:时间限制</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">redirect:在访问的路径是目录的时候，如果允许redirect，则会redirect到这个目录下的index.html文件，默认为true</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">callback:在每次静态服务之后调用的函数（包括发生错误，发生错误之后不会再调用next）。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">hidden:是否允许访问隐藏文件（默认为false）</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br clear="none" /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">根据这些参数来决定访问限制。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br clear="none" /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">支持conditional和range。</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "><br clear="none" /></span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">最终通过</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">var stream = fs.createReadStream(path, opts);</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">stream.pipe(res);</span></div><div><span style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; ">管道的方式来传送文件内容。</span></div></div></span></div></div></div></span></div></div><p>&nbsp;</p></div></div><img src ="http://www.cppblog.com/dead-horse/aggbug/161007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-11-26 21:01 <a href="http://www.cppblog.com/dead-horse/archive/2011/11/26/161007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++与javascript对比</title><link>http://www.cppblog.com/dead-horse/archive/2011/10/15/158323.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Fri, 14 Oct 2011 18:42:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/10/15/158323.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/158323.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/10/15/158323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/158323.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/158323.html</trackback:ping><description><![CDATA[<div><p><span class="Apple-style-span" style="font-size: 12px;"><br /></span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">接触</span><span style="font-size:9.0pt">javascript</span><span style="font-size: 9.0pt;font-family:宋体;">应该有三个月了，但是一直没有认真去学习这门语言的一些特性，现在结合</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">的语言特性来分析一下，对自己脑海中的知识做个总结。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">1</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">是静态语言，</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt;font-family:宋体;">是动态语言。区别如下：</span><span style="font-size: 12.0pt;font-family:宋体;"> </span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">静态语言：</span></p>  <p><span style="font-size:9.0pt">1.</span><span style="font-size:9.0pt;font-family:宋体;">在不执行的时候也能够做类型检测，可以一定程度上的检测出一些逻辑错误。但是过多的声明使得程序变得冗余。</span></p>  <p><span style="font-size:9.0pt">2.</span><span style="font-size:9.0pt;font-family:宋体;">编写代码开始的时候就要考虑变量和算式应该是什么类型，有利于编写好的、高可用性的程序。</span></p>  <p><span style="font-size:9.0pt">3.</span><span style="font-size:9.0pt;font-family:宋体;">对编译器提示有作用，同时也对理解代码有作用。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">问题：灵活性不够，不定义类型无法写程序。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">动态语言：</span></p>  <p><span style="font-size:9.0pt">1.</span><span style="font-size:9.0pt;font-family:宋体;">最大优点是代码简洁。</span></p>  <p><span style="font-size:9.0pt">2.</span><span style="font-size:9.0pt;font-family:宋体;">十分灵活。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">问题：运行速度相对会慢一些，要做类型检查。最大缺点是不执行就无法检测出错误。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">2</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">是编译型语言，</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt;font-family:宋体;">是解释型语言。</span></p>  <p><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt;font-family:宋体;">的编译过程：预处理</span><span style="font-size:9.0pt">-&gt;</span><span style="font-size:9.0pt; font-family:宋体;">编译优化</span><span style="font-size:9.0pt">-&gt;</span><span style="font-size:9.0pt;font-family: 宋体;">汇编</span><span style="font-size: 9.0pt">-&gt;</span><span style="font-size:9.0pt;font-family:宋体;">链接。</span></p>  <p><span style="font-size:9.0pt">Js</span><span style="font-size:9.0pt;font-family:宋体;">的解析机制：预处理（分段读取代码预处理）</span><span style="font-size:9.0pt">-&gt;</span><span style="font-size:9.0pt; font-family:宋体;">解释执行</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">3</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">有指针，</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt;font-family:宋体;">无指针。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">在</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">中的赋值，所有的基本类型都是直接复制，而自定义类型因为有指针的存在，可以自己选择进行深复制（复制）还是浅复制（引用）。而在</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt; font-family:宋体;">中，所有的基本类型赋值都是复制，而所有的其他类型赋值都是引用。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">4</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt; font-family:宋体;">是函数式编程语言，</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt;font-family: 宋体;">不是。</span></p>  <p><span style="font-size:9.0pt">Js</span><span style="font-size:9.0pt;font-family:宋体;">把函数当作对象来处理，可以将它当作函数的输入参数和输出值（高阶函数）。</span></p>  <p><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt;font-family:宋体;">如果要把函数当作其他函数的输入参数，即实现高阶函数，必须要通过函数指针（经常还要多传递一个（</span><span style="font-size:9.0pt">void *</span><span style="font-size:9.0pt; font-family:宋体;">）类型的参数作为参数的函数的参数）。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">5</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">的继承是基于类的，</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt;font-family:宋体;">的继承基于原型</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">在</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt; font-family:宋体;">中，继承是通过类来进行的。比较符合人的直观思维。同时在生成一个类之后，是不能够对它进行修改了，除非再去修改它的定义。（</span><span style="font-size:9.0pt">Ruby</span><span style="font-size:9.0pt; font-family:宋体;">基于开放类的继承可以在定义之后任意追加类的内容）</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">在</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt; font-family:宋体;">中，继承则是通过原型链的方式来进行的。同样也可以在定义之后修改原型链。同时，也可以修改内置类型的原型链来扩展内置类型（慎用，</span><span style="font-size:9.0pt">monkey patching</span><span style="font-size:9.0pt;font-family:宋体;">可能导致内置对象大幅度修改产生难以预期的行为）。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt;font-family:宋体;">（</span><span style="font-size:9.0pt">JS</span><span style="font-size:9.0pt; font-family:宋体;">特性）</span></p>  <p><span style="font-size:9.0pt">6</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt; font-family:宋体;">的一个重要特性是闭包（当前作用域可以访问并保存外部作用域的变量）。</span></p>  <p><span style="font-size:9.0pt">Js</span><span style="font-size:9.0pt;font-family:宋体;">的闭包在函数返回之后，还能够保持闭包引用到的变量不释放。其最大的用途有两个：一是可以函数返回闭包，让外面可以读取访问到函数内的值，二是让这些变量的值一直保存在内存之中不释放。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">有闭包很容易实现内部迭代器（</span><span style="font-size:9.0pt">each</span><span style="font-size:9.0pt; font-family:宋体;">方法），而</span><span style="font-size:9.0pt">C++</span><span style="font-size:9.0pt;font-family: 宋体;">没有闭包，共有循环外部信息比较麻烦，采取的是外部迭代器方法（</span><span style="font-size:9.0pt">vector&lt;int&gt;::iterator</span><span style="font-size:9.0pt;font-family:宋体;">）。</span></p>  <p><span style="font-size:9.0pt;font-family:宋体;">注意事项：</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size:9.0pt;"><span>1.<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size:9.0pt;font-family:宋体;">如果滥用闭包容易消耗大量内存，同时在</span><span style="font-size:9.0pt">IE</span><span style="font-size:9.0pt;font-family:宋体;">中会有内存泄漏问题，所以在退出函数之前将不使用的局部变量全部删除。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size:9.0pt;"><span>2.<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size:9.0pt;font-family:宋体;">闭包也会在外部改变父函数内部的值，因此用闭包当共有方法的时候要注意不要随便改变内部的值。</span></p>  <p>&nbsp;</p>  <p><span style="font-size:9.0pt">7</span><span style="font-size:9.0pt;font-family:宋体;">、</span><span style="font-size:9.0pt">js</span><span style="font-size:9.0pt; font-family:宋体;">可以显示的设置上下文。</span></p>  <p><span style="font-size:9.0pt">Js</span><span style="font-size:9.0pt;font-family:宋体;">可以通过</span><span style="font-size:9.0pt">applay</span><span style="font-size:9.0pt; font-family:宋体;">和</span><span style="font-size:9.0pt">call</span><span style="font-size:9.0pt;font-family: 宋体;">方法显示指定函数内的</span><span style="font-size:9.0pt">this</span><span style="font-size:9.0pt;font-family: 宋体;">。</span><span style="font-size: 9.0pt">applay</span><span style="font-size:9.0pt;font-family:宋体;">参数传递用数组，</span><span style="font-size:9.0pt">call</span><span style="font-size:9.0pt; font-family:宋体;">参数分开传。</span></p>  <p>（未完待续）&nbsp;</p>  <p><span style="font-size:9.0pt;font-family:宋体;">上述浅薄个人看法，如果有错误希望大家能够指正。</span></p></div><img src ="http://www.cppblog.com/dead-horse/aggbug/158323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-10-15 02:42 <a href="http://www.cppblog.com/dead-horse/archive/2011/10/15/158323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Nodejs + mongoDB 使用初体验</title><link>http://www.cppblog.com/dead-horse/archive/2011/09/23/156617.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Fri, 23 Sep 2011 07:15:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/09/23/156617.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/156617.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/09/23/156617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/156617.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/156617.html</trackback:ping><description><![CDATA[<div> 	<title></title> 	 	   <pre>  最近在做nodejs的web开发，初次接触到mongoDB这个数据库。<br />  其实之前对关系型数据库的接触也不是很多，不过在刚接触使用mongoDB的时候还是习惯性的把关系型数据库的设计思维带了进去。在设计数据库的时候，还是把一些关系型数据库设计的思维带进去了，没有发挥出mongoDB文档型数据库的优势。mongoDB可以方便的把一些本来mySQL需要通过一对多关系关联的数据通过数组+对象的方式作为一个文档存储到一个collections里面，并且提供了各种API支持对一个文档里面的数组进行操作。    此次实践选用的node中间件是mongoskin，不过惭愧的是基本没有用到mongoskin的太多特性，基本当作node-mongodb-native来使用。不过写完之后，对于mongoDB的查询API以及node同mongoDB的交互有了一定的了解。<br />  <br />  MongoDB常用查询方法与在node中的体现：  <br />1）数据库连接 <br />mongoDB： mongo -u username -p password host:port/dbs <br />node+mongoSkin: require(&#8220;mongoskin&#8221;).db(username:password@host:port/dbs);  <br /> <br />2)索引 person.ensureIndex({&#8220;name&#8221;:1},{&#8220;unique&#8221;:true}, callback);<br />第一个参数是selector，第二个参数是选项，有unique（唯一索引）等mongoDB索引选项。<br />ensureIndex先查找是否存在这个索引，如果不存在，则建立索引，因此不会出现重复建立的情况。<br /><br />3）新建数据<br />person.save({&#8220;name&#8221;:&#8221;jobs&#8221;, age:32, gender:&#8221;male&#8221;}, callback);<br />person.save({&#8220;name&#8221;：&#8221;tim&#8221;, age:29, gender:&#8221;male&#8221;}, callback);<br /><br />4）查询 <br />findOne方法：查询符合selector条件的结果，取第一条给callBack，err是错误信息，如果没有错误，则为undefined，data数据为一个js对象。 <br />person.findOne({&#8220;name&#8220;:&#8221;jobs&#8221;}), callBack(err, data));  <br /><br />find方法：查询符合selector条件，并且还可以加入一系列参数，最后通过toArray方法，把数据生成数组的方式传递给callback。 <br />person.find({&#8220;gender&#8221;:&#8221;male&#8221;},{sort:[['name', 1]],skip:pageNum*(page-1), limit:pageNum}).toArray(callback(err, data){}) <br />同时查询的时候可以通过$in,$gt,$lt等方式来确定selector的范围。  <br /><br />5）更改 <br />有两点要注意：<br />1.update方法如果是要更新文档中的一个或几个属性的时候，必须要用形如{$set:{age:33}}的形式，如果写成{age:33}的形式，则这个文档的其他内容都会被删除，只剩{age:32}这一个属性。 <br />2.update方法默认是只更新找到的第一个文档，如果需要所有的文档都更新，则需要在option部分再加上{multi:true},如果想要在查找不到这条记录的时候新增一条，则要在option部分加上{upsert:true}。 <br />person.update({&#8220;name&#8221;:&#8221;jobs&#8221;}, {$set{&#8220;age&#8221;:33}}, {multi:true}, callback(err))  <br /><br />6)删除 person.remove({&#8220;name&#8221;:&#8221;jobs&#8221;},callback(err){});  <br /><br />7）selector中使用mongoDB自动生成的_id <br />mongoDB会为每一个文档生成一个_id属性，类似于mySQL的主键，是唯一的。_id的类型是mongoDB自己定义的objectID类型，因此尽管在查询的时候可以得到一个12位或者24位的_id字符串，但是如果想在selector里面通过_id进行查找或其他操作的时候，必须要先通过db.collection.id()方法进行类型转换。 <br />person.remove({&#8220;_id&#8221;:person.id(stringID)}, callback(err){});  <br /><br />8）mongoDB对文档内的数组进行操作（通过update方法） <br />1.通过$addToSet方法向数组中插入记录，插入前该方法会先查找是否存在这条记录，如果存在则不插入。如果想要插入重复的值，则可以通过$push进行添加。 <br />person.update({&#8220;name&#8221;:&#8221;jobs&#8221;}, {$addToSet: {<br /><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">company: {<br /></span><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">name: &#8220;google&#8221;,<br /></span><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">address: USA,<br /></span><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">workingTime: 3<br /></span><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">}<br /></span><span class="Apple-style-span" style="font-family: verdana, 'courier new'; white-space: normal; ">}, function(err){});</span></pre> <p align="LEFT" style="margin-bottom: 0cm"><br /> </p> <p align="LEFT" style="margin-bottom: 0cm">2.修改数组中的数据：通过$符。如果在数组中查询的时候要匹配两个属性，必须要使用$elemMatch方法，如果只通过{"name":&#8221;google&#8221;, "address":USA}去查找，会选择到所有name为google或者address为USA的元素。在定位到这个元素之后，通过$来选定它进行修改。</p> <p align="LEFT" style="margin-bottom: 0cm">person.update({</p> <p align="LEFT" style="margin-bottom: 0cm">    &#8220;name&#8221;:&#8221;jobs&#8221;,</p> <p align="LEFT" style="margin-bottom: 0cm">    company:{$elemMatch:{"name":&#8221;google&#8221;, "address":USA}}</p> <p align="LEFT" style="margin-bottom: 0cm">  }, {$set:{"company.$.workingTime":4}},function(){})</p> <p align="LEFT" style="margin-bottom: 0cm"><br /> </p> <p align="LEFT" style="margin-bottom: 0cm">3.删除数组中的数据：通过$pull方法</p> <p align="LEFT" style="margin-bottom: 0cm">person.update({</p> <p align="LEFT" style="margin-bottom: 0cm">    &#8220;name&#8221;:&#8221;jobs&#8221;,</p> <p align="LEFT" style="margin-bottom: 0cm">  },{$pull:{company:{&#8220;name&#8221;:&#8221;google&#8221;, &#8220;address&#8221;:&#8221;USA&#8221;}}},function(err){})</p></div><img src ="http://www.cppblog.com/dead-horse/aggbug/156617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-09-23 15:15 <a href="http://www.cppblog.com/dead-horse/archive/2011/09/23/156617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>g++基础知识</title><link>http://www.cppblog.com/dead-horse/archive/2011/09/22/156493.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Wed, 21 Sep 2011 19:59:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/09/22/156493.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/156493.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/09/22/156493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/156493.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/156493.html</trackback:ping><description><![CDATA[<div> 	<title></title> 	 	   <pre>一、编译过程： <br />1）预处理，生成.i文件 <br />2）转换成为汇编语言，生成.s文件 <br />3）汇编变为目标代码（机器代码），生成.o文件 <br />4）链接目标代码，生成可执行程序。  <br /><br />二、常用编译选项 <br />tips：选项必须独立给出：&#8216;-pg&#8217;和&#8216;-p -g&#8217;完全不同  <br /><br />-c：编译或汇编源文件，不做连接。 <br />G++ -c test.cpp输出test.o  <br /><br />-o file：制定输出文件为file  <br /><br />-Wall： 输出所有编译警告（最好加上）  <br /><br />-Dmacro=XXX：定义宏。  <br /><br />-shared：生成一个共享库文件 <br />g++ -shared -o libtest.so test.o  <br /><br />-fPIC：生成位置无关目标代码，适用于动态连接。  <br /><br />-llibrarytest：连接名字为librarytest的库 <br />真正名字是liblibrarytest.so(a) so是动态库，a是静态库。 <br />严格按照文件名搜索，版本号要创建软连接。 <br />编译搜索目录：<br />用户-L指定， LIBRARY_PATH，系统目录/lib  /usr/lib <br />运行搜索目录：<br />LD_LIBRARY_PATH，ld.so.cache &amp; /etc/ld.so.conf ，系统目录  /lib  /usr/lib <br />动态库和静态库同名，优先动态库。  <br /><br />-Ldir：添加库文件搜索路径 -Idir（include）：添加头文件搜索路径  <br /><br />-g：产生调试信息  <br /><br />-olevel：优化级别，一般用o2  <br /><br />三、静态库、共享库 <br />静态库：一些.o文件打包，在被连接后成为程序的一部分。 <br />编译方法 <br />-g++ -c test.cpp <br />-ar res libtest.a test.o <br />链接方法： <br />-g++ -Wall -o test testMain.cpp -ltest -L./  <br /><br />共享库：链接的时候不会被复制到程序中。 <br />编译方法： <br />g++ -c fPIC test.cpp	<br />//要动态 g++ -shared -WI, -soname, libtest.so, -o libtest.so.1.0.1 test.o <br />mv libtest.so.1.0.1 /usr/lib <br />sudo ldconfig &amp; || ll /user/lib/libtest.so //创建一个软连接。     <br />链接方法：<br />g++ -o test test.cpp ./libtest.so -ldx_cxx  <br /><br />四、常用命令 <br />ldd：显示程序依赖的同台共享库。  <br />file：查看文件格式信息。  <br />ldconfig：在搜寻目录下搜索出可以共享的动态链接库 </pre></div><img src ="http://www.cppblog.com/dead-horse/aggbug/156493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-09-22 03:59 <a href="http://www.cppblog.com/dead-horse/archive/2011/09/22/156493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>nodeJS + mongoDB简单多表查询与js 数组去重</title><link>http://www.cppblog.com/dead-horse/archive/2011/09/14/155717.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Tue, 13 Sep 2011 17:42:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/09/14/155717.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/155717.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/09/14/155717.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/155717.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/155717.html</trackback:ping><description><![CDATA[&nbsp; mongoDB是不支持多表查询的，而nodeJS又是异步的，导致多表查询比较麻烦。<br />&nbsp; 一个十分简陋的多表查询方法（只有一个关联条件）：先从第一个collection中查询得到数据，将其中两个collection关联的field从中取出来并去重，通过$in在第二个collections中查询。<br />&nbsp; &nbsp;在写数组去重的时候，发现js语言特性写这种函数比C++轻松太多。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;users&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;[],&nbsp;uhash</span><span style="color: #000000; ">=</span><span style="color: #000000; ">{};</span><span style="color: #008000; ">//</span><span style="color: #008000; ">uhash是辅助用hash表</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,&nbsp;len</span><span style="color: #000000; ">=</span><span style="color: #000000; ">data.length;&nbsp;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">length;&nbsp;</span><span style="color: #000000; ">++</span><span style="color: #000000; ">i){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(!uhash[data[i].email])&nbsp;{</span><span style="color: #008000; ">//</span><span style="color: #008000; ">只有hash表中不存在再插入</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uhash[data[i].email]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;users.push(data[i].email);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><br />&nbsp; hash可以非常方便的帮助完成一些辅助数组的任务。<img src ="http://www.cppblog.com/dead-horse/aggbug/155717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-09-14 01:42 <a href="http://www.cppblog.com/dead-horse/archive/2011/09/14/155717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NAE管理系统开发（nodejs+express+mongoDB）小结</title><link>http://www.cppblog.com/dead-horse/archive/2011/08/24/154190.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Tue, 23 Aug 2011 17:48:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/08/24/154190.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/154190.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/08/24/154190.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/154190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/154190.html</trackback:ping><description><![CDATA[&nbsp; 这算是我第一个web的程序，写的各种丑陋不堪..记录一些不算收获的东西。看到哪写到哪。<br /><br />&nbsp; 1、路由中间件：用户登录检测和权限检测可以交给路由中间件去处理。<br /><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "><br />app.post(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">/application/manage/:id/coopmng</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;hasLogin,&nbsp;checkChangeAuth(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">infoRight</span><span style="color: #000000; ">"</span><span style="color: #000000; ">),&nbsp;manager.doCoopmng);</span></div>&nbsp; checkChangeAuth通过返回一个函数，所以可以在路由中间件中传递参数进去，更加灵活。<br /><br />&nbsp; 2、通过prototype，可以十分轻易的扩展内置的对象：扩展Date，添加format方法。<br /><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; ">*<br />*&nbsp;时间对象的格式化;<br /></span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />Date.prototype.format&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(format){<br />&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;*&nbsp;eg:format="YYYY-MM-dd&nbsp;hh:mm:ss";<br />&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;o&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;{<br />&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">M+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getMonth()</span><span style="color: #000000; ">+</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">month</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">d+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getDate(),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">day</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">h+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getHours(),&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">hour</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">m+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getMinutes(),&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">minute</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">s+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getSeconds(),&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">second</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">q+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;:&nbsp;&nbsp;Math.floor((</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getMonth()</span><span style="color: #000000; ">+</span><span style="color: #000000; ">3</span><span style="color: #000000; ">)</span><span style="color: #000000; ">/</span><span style="color: #000000; ">3</span><span style="color: #000000; ">),&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">quarter</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">S</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;&nbsp;:&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getMilliseconds()&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">millisecond</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #000000; ">/</span><span style="color: #000000; ">((</span><span style="color: #000000; ">|</span><span style="color: #000000; ">Y</span><span style="color: #000000; ">|</span><span style="color: #000000; ">)</span><span style="color: #000000; ">+</span><span style="color: #000000; ">)</span><span style="color: #000000; ">/</span><span style="color: #000000; ">.test(format))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;format&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;format.replace(RegExp.$</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;(</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.getFullYear()</span><span style="color: #000000; ">+</span><span style="color: #000000; ">""</span><span style="color: #000000; ">).substr(</span><span style="color: #000000; ">4</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;RegExp.$</span><span style="color: #000000; ">1</span><span style="color: #000000; ">.length));<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">var</span><span style="color: #000000; ">&nbsp;k&nbsp;</span><span style="color: #0000FF; ">in</span><span style="color: #000000; ">&nbsp;o)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;RegExp(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;k&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).test(format))&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;format.replace(RegExp.$</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,&nbsp;RegExp.$</span><span style="color: #000000; ">1</span><span style="color: #000000; ">.length</span><span style="color: #000000; ">==</span><span style="color: #000000; ">1</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;o[k]&nbsp;:&nbsp;(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">00</span><span style="color: #000000; ">"</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;o[k]).substr((</span><span style="color: #000000; ">""</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;o[k]).length));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;format;<br />}</span></div>&nbsp;&nbsp;<br />&nbsp; 3、cookie处理：在登录的时候，给它设置一个cookie，设定好过期时间，内容包含：userName,timestamp,checkCode=md5(userName, password, timestamp, skey)。skey是保存在服务器端的一个私钥。在登录验证cookie的时候，先检测时间是否过期（不能只依靠cookie的自动失效），然后再取出user现在的password，重新计算checkCode。可以保证用户修改密码后之前的cookie会失效。<br /><br />&nbsp; &nbsp;4、通过eventProxy，可以并行查询数据库，提高效率，同时让代码简洁。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp; &nbsp; checkEventProxy.assign(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkName</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkEmail</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(goodName,&nbsp;goodEmail){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(goodName);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">goodName)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;res.render(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">error</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;{message:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">昵称已经被注册</span><span style="color: #000000; ">"</span><span style="color: #000000; ">});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(</span><span style="color: #000000; ">!</span><span style="color: #000000; ">goodEmail)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;res.render(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">error</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;{message:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">email已经被注册</span><span style="color: #000000; ">"</span><span style="color: #000000; ">});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;users.save({email:userEmail,&nbsp;nickName:userNickName,&nbsp;password:userPassword},&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(err){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(err){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(err);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;res.render(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">error</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;{message:</span><span style="color: #000000; ">"</span><span style="color: #000000; ">注册失败，请稍后再试</span><span style="color: #000000; ">"</span><span style="color: #000000; ">});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.session.email&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;userEmail;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.session.nickName&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;userNickName;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res.redirect(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">/application</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">检查email是否已经存在</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;users.findOne({email:userEmail.toString()},</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(err,&nbsp;item){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(err){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(err);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkEmail</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(item)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkEmail</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkEmail</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">检查昵称是否已经存在</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;users.findOne({nickName:userNickName.toString()},&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(err,&nbsp;item){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(err){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(err);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkName</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000FF; ">else</span><span style="color: #000000; ">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(item)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkName</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">false</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkEventProxy.trigger(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">checkName</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><br />&nbsp; 5、通过谷歌smtp.gmail.com或者其他的smtp服务提供商，可以发送邮件（不需要sendmail支持）。nodemailer模块（npm install nodemailer）可以十分简单的发送邮件以及附件。<br /><br />&nbsp; 6、mongoDB不支持多表查询，所以可能要有适当的数据表项冗余。同时mongoDB不提供事务，也无法完全保证原子性。<br />&nbsp; &nbsp; &nbsp;mongoDB选定collection后的增删查改操作:<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">db.collections(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">users</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).findOne({userEmail:email},{nickName:</span><span style="color: #000000; ">1</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">查询结果包含nickName</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">},&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(err,data){});</span></div><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">db.collections(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">users</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).find({userEmail:email},{skip:</span><span style="color: #000000; ">10</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">跳过10条记录</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">,&nbsp;limit:</span><span style="color: #000000; ">10</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">结果最多10条，。实现分页功能</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">}).toArray(</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(err,data){});</span></div><br /><div style="background-color: #eeeeee; font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">db.collections(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">users</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).save({</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">save的内容</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">},&nbsp;</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(){})</span><span style="color: #008000; ">//</span><span style="color: #008000; ">插入</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">db.collections(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">users</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).remove({</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">条件</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">},</span><span style="color: #0000FF; ">function</span><span style="color: #000000; ">(){})<br />db.collections(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">users</span><span style="color: #000000; ">"</span><span style="color: #000000; ">).update({</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">条件</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">},{$set:{</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">内容</span><span style="color: #008000; ">*/</span><span style="color: #000000; ">}})</span></div><br />&nbsp; 7、div通过float左右分屏的时候，必须要在它们的父div添加fixClear类。通过添加一个隐藏的元素在父div最下方，让浏览器检测到两个左右浮动的div的高度，从而不会出现显示错误。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #800000; ">.clearfix:after&nbsp;</span><span style="color: #000000; ">{</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;content</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;"."</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;display</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;block</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;clear</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;both</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;visibility</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;hidden</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;line-height</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;0</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;height</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;0</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br /></span><span style="color: #000000; ">}</span><span style="color: #800000; "><br />&nbsp;<br />.clearfix&nbsp;</span><span style="color: #000000; ">{</span><span style="color: #FF0000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;display</span><span style="color: #000000; ">:</span><span style="color: #0000FF; ">&nbsp;inline-block</span><span style="color: #000000; ">;</span><span style="color: #FF0000; "><br /></span><span style="color: #000000; ">}</span><span style="color: #800000; "><br />&nbsp;</span></div><br />&nbsp; 8.express的session，默认是存为持久的，像cookie一样要到一定时间才过期。在存session的时候，通过把req.session.cookie.expires设置成为false，可以将session设置为非持久，这样在浏览器关闭的时候，session就会消掉。<img src ="http://www.cppblog.com/dead-horse/aggbug/154190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-08-24 01:48 <a href="http://www.cppblog.com/dead-horse/archive/2011/08/24/154190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eventProxy解析</title><link>http://www.cppblog.com/dead-horse/archive/2011/08/18/153563.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Thu, 18 Aug 2011 07:24:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/08/18/153563.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/153563.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/08/18/153563.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/153563.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/153563.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; &nbsp;在写node.js的时候，经常会遇到要去数据库的多个地方取得多个数据，然后才能进行下一步的操作的情况。如果是线性执行的语言，通常的做法是一条一条去取，全部取到之后再进行下一步操作。然而在node里面，因为是基于事件的，所以只能够一层一层的在回调函数里面嵌套进去。取到第一个数据之后，执行回调函数去取第二条数据，然后再执行回调函数。&nbsp; &nbsp;对于node来...&nbsp;&nbsp;<a href='http://www.cppblog.com/dead-horse/archive/2011/08/18/153563.html'>阅读全文</a><img src ="http://www.cppblog.com/dead-horse/aggbug/153563.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-08-18 15:24 <a href="http://www.cppblog.com/dead-horse/archive/2011/08/18/153563.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>node "Can't set headers after they are sent"</title><link>http://www.cppblog.com/dead-horse/archive/2011/08/12/153110.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Thu, 11 Aug 2011 17:08:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/08/12/153110.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/153110.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/08/12/153110.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/153110.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/153110.html</trackback:ping><description><![CDATA[&nbsp; &nbsp;最近刚开始接触web开发，学习node.js，在写的时候经常会出现Can't set headers after they are sent这个错误。<br />&nbsp; &nbsp;发现是在redirect或者render之后，node并不会跳出代码段，中断下面的执行，而是继续往下执行，当再次redirect或者render的时候，就会出现这个错误。<br /><br />&nbsp; &nbsp;要在redirect和render之前适时加上return，结束它们之后的代码执行，可以避免这个错误。<img src ="http://www.cppblog.com/dead-horse/aggbug/153110.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-08-12 01:08 <a href="http://www.cppblog.com/dead-horse/archive/2011/08/12/153110.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL算法（STL源码剖析）</title><link>http://www.cppblog.com/dead-horse/archive/2011/06/08/118017.html</link><dc:creator>dead_horse</dc:creator><author>dead_horse</author><pubDate>Tue, 07 Jun 2011 17:06:00 GMT</pubDate><guid>http://www.cppblog.com/dead-horse/archive/2011/06/08/118017.html</guid><wfw:comment>http://www.cppblog.com/dead-horse/comments/118017.html</wfw:comment><comments>http://www.cppblog.com/dead-horse/archive/2011/06/08/118017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/dead-horse/comments/commentRss/118017.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/dead-horse/services/trackbacks/118017.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;lower_bound&amp;upper_bound是二分查找的一种版本，在已排序的区间中寻找可插入value的第一个位置和第一个不小于value的位置。<br />&nbsp;&nbsp;&nbsp;lower_bound的实现（forward_iteratror版本，其random_access_iterator版本不需要用distance函数，直接用+）：<br /></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ForwardIterator,&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;T,&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Distance</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />ForwardIterator&nbsp;__lower_bound(ForwardIterator&nbsp;first,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;ForwardIterator&nbsp;last,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;value,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;Distance</span><span style="color: #000000">*</span><span style="color: #000000">,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;forward_iterator_tag)<br /><img id="Codehighlighter1_217_539_Open_Image" onclick="this.style.display='none'; Codehighlighter1_217_539_Open_Text.style.display='none'; Codehighlighter1_217_539_Closed_Image.style.display='inline'; Codehighlighter1_217_539_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_217_539_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_217_539_Closed_Text.style.display='none'; Codehighlighter1_217_539_Open_Image.style.display='inline'; Codehighlighter1_217_539_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_217_539_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_217_539_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;Distance&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;distance(first,&nbsp;last,&nbsp;len);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">求整个区间的长度</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Distance&nbsp;half;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ForwardIterator&nbsp;middle;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(len</span><span style="color: #000000">&gt;</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_333_522_Open_Image" onclick="this.style.display='none'; Codehighlighter1_333_522_Open_Text.style.display='none'; Codehighlighter1_333_522_Closed_Image.style.display='inline'; Codehighlighter1_333_522_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_333_522_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_333_522_Closed_Text.style.display='none'; Codehighlighter1_333_522_Open_Image.style.display='inline'; Codehighlighter1_333_522_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_333_522_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_333_522_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;half</span><span style="color: #000000">=</span><span style="color: #000000">len</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">除以二</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;middle</span><span style="color: #000000">=</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;advance(middle,&nbsp;half);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">middle指向中间位置</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">middle</span><span style="color: #000000">&lt;</span><span style="color: #000000">value)<br /><img id="Codehighlighter1_436_499_Open_Image" onclick="this.style.display='none'; Codehighlighter1_436_499_Open_Text.style.display='none'; Codehighlighter1_436_499_Closed_Image.style.display='inline'; Codehighlighter1_436_499_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_436_499_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_436_499_Closed_Text.style.display='none'; Codehighlighter1_436_499_Open_Image.style.display='inline'; Codehighlighter1_436_499_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_436_499_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_436_499_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;middle;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">len</span><span style="color: #000000">-</span><span style="color: #000000">half</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">修正len</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">half;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<br />upper_bound的实现（forward_iterator版本）：<br /><br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ForwardIterator,&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;T,&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Distance</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />ForwardIterator&nbsp;__lower_bound(ForwardIterator&nbsp;first,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;ForwardIterator&nbsp;last,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;value,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;Distance</span><span style="color: #000000">*</span><span style="color: #000000">,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;forward_iterator_tag)<br /><img id="Codehighlighter1_217_547_Open_Image" onclick="this.style.display='none'; Codehighlighter1_217_547_Open_Text.style.display='none'; Codehighlighter1_217_547_Closed_Image.style.display='inline'; Codehighlighter1_217_547_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_217_547_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_217_547_Closed_Text.style.display='none'; Codehighlighter1_217_547_Open_Image.style.display='inline'; Codehighlighter1_217_547_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_217_547_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_217_547_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;Distance&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;distance(first,&nbsp;last,&nbsp;len);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">求整个区间的长度</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Distance&nbsp;half;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;ForwardIterator&nbsp;middle;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(len</span><span style="color: #000000">&gt;</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_333_530_Open_Image" onclick="this.style.display='none'; Codehighlighter1_333_530_Open_Text.style.display='none'; Codehighlighter1_333_530_Closed_Image.style.display='inline'; Codehighlighter1_333_530_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_333_530_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_333_530_Closed_Text.style.display='none'; Codehighlighter1_333_530_Open_Image.style.display='inline'; Codehighlighter1_333_530_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_333_530_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_333_530_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;half</span><span style="color: #000000">=</span><span style="color: #000000">len</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">除以二</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;middle</span><span style="color: #000000">=</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;advance(middle,&nbsp;half);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">middle指向中间位置</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(value</span><span style="color: #000000">&lt;*</span><span style="color: #000000">middle)<br /><img id="Codehighlighter1_436_453_Open_Image" onclick="this.style.display='none'; Codehighlighter1_436_453_Open_Text.style.display='none'; Codehighlighter1_436_453_Closed_Image.style.display='inline'; Codehighlighter1_436_453_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_436_453_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_436_453_Closed_Text.style.display='none'; Codehighlighter1_436_453_Open_Image.style.display='inline'; Codehighlighter1_436_453_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_436_453_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_436_453_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">half;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br /><img id="Codehighlighter1_464_527_Open_Image" onclick="this.style.display='none'; Codehighlighter1_464_527_Open_Text.style.display='none'; Codehighlighter1_464_527_Closed_Image.style.display='inline'; Codehighlighter1_464_527_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_464_527_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_464_527_Closed_Text.style.display='none'; Codehighlighter1_464_527_Open_Image.style.display='inline'; Codehighlighter1_464_527_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_464_527_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_464_527_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;middle;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len</span><span style="color: #000000">=</span><span style="color: #000000">len</span><span style="color: #000000">-</span><span style="color: #000000">half</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">修正len</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />&nbsp;&nbsp;&nbsp;upper_bound和lower_bound的区别在于取等号时的做法。upper_bound将等号放在大于号一起处理，lower_bound则相反，因此两者最终得到的结果也不同。binary_search（）可以通过lower_bound得到。<br /><br />排序算法（重点）：<br />&nbsp;&nbsp;&nbsp;partial_sort：将一个区间内的前N个元素进行排序。<br />&nbsp;&nbsp;&nbsp;方法：堆排序：（从小到大排序）先将前N个元素make_heap，生成一个max_heap，然后对N+1~size的元素与max_heap的顶依次比较，如果比堆顶元素小，则交换两元素位置，再对堆进行重排。循环过后再对堆进行sort_heap。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">make_heap(first,&nbsp;middle);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">for</span><span style="color: #000000">(RandomAccessIterator&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;middle;&nbsp;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">last;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">i)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">只能是随机迭代器</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">i</span><span style="color: #000000">&lt;*</span><span style="color: #000000">first)<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__pop_heap(first,&nbsp;middle,&nbsp;i&nbsp;,T(</span><span style="color: #000000">*</span><span style="color: #000000">i),&nbsp;dfistance_type(first));<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;sort_heap(first,&nbsp;middle);</span></div>
<br />&nbsp;&nbsp;&nbsp;sort：对所给区间进行排序。<br />&nbsp;&nbsp;&nbsp;方法：快速排序（改进版），改进方法：结合插入排序、采用三点中值法选区pivot，使用内省式排序（在结合插入排序、三点中值法的同时，检测如果递归次数达到限定次数时，改为使用堆排序，防止出现二次的时间效率。）<br />&nbsp;&nbsp;&nbsp;sort接受两个随机迭代器作为参数（只有随机迭代器能够使用sort）<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">inline&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;sort(RandomAccessIterator&nbsp;first,&nbsp;RandomAccessIterator&nbsp;last)<br /><img id="Codehighlighter1_72_241_Open_Image" onclick="this.style.display='none'; Codehighlighter1_72_241_Open_Text.style.display='none'; Codehighlighter1_72_241_Closed_Image.style.display='inline'; Codehighlighter1_72_241_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_72_241_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_72_241_Closed_Text.style.display='none'; Codehighlighter1_72_241_Open_Image.style.display='inline'; Codehighlighter1_72_241_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_72_241_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_72_241_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(first&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;last)<br /><img id="Codehighlighter1_94_239_Open_Image" onclick="this.style.display='none'; Codehighlighter1_94_239_Open_Text.style.display='none'; Codehighlighter1_94_239_Closed_Image.style.display='inline'; Codehighlighter1_94_239_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_94_239_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_94_239_Closed_Text.style.display='none'; Codehighlighter1_94_239_Open_Image.style.display='inline'; Codehighlighter1_94_239_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_94_239_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_94_239_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__introsort_loop(first,&nbsp;last,&nbsp;value_type(first)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">内省式排序</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&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;__lg(last</span><span style="color: #000000">-</span><span style="color: #000000">first)</span><span style="color: #000000">*</span><span style="color: #000000">2</span><span style="color: #000000">);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__final_insertion_sort(first,&nbsp;last);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">最终进行一次插入排序</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<br />&nbsp;&nbsp;&nbsp;__lg()用来控制最多的递归次数,找出2^k&lt;n的最大K。当个数为40时，得到5。5*2=10为最多允许分割层数。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Size</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />inline&nbsp;Size&nbsp;__lg(size&nbsp;n)<br /><img id="Codehighlighter1_46_95_Open_Image" onclick="this.style.display='none'; Codehighlighter1_46_95_Open_Text.style.display='none'; Codehighlighter1_46_95_Closed_Image.style.display='inline'; Codehighlighter1_46_95_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_46_95_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_46_95_Closed_Text.style.display='none'; Codehighlighter1_46_95_Open_Image.style.display='inline'; Codehighlighter1_46_95_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_46_95_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_46_95_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;Size&nbsp;k;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(k</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;n</span><span style="color: #000000">&gt;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;n</span><span style="color: #000000">&gt;&gt;=</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">k;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;k;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<br />&nbsp;&nbsp;&nbsp;&nbsp;
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;__introsort_loop(RandomAccessIterator&nbsp;first,&nbsp;RandomAccessIterator&nbsp;last.<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;Size&nbsp;depth_limit)<br /><img id="Codehighlighter1_106_555_Open_Image" onclick="this.style.display='none'; Codehighlighter1_106_555_Open_Text.style.display='none'; Codehighlighter1_106_555_Closed_Image.style.display='inline'; Codehighlighter1_106_555_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_106_555_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_106_555_Closed_Text.style.display='none'; Codehighlighter1_106_555_Open_Image.style.display='inline'; Codehighlighter1_106_555_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_106_555_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_106_555_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(last</span><span style="color: #000000">-</span><span style="color: #000000">first</span><span style="color: #000000">&gt;</span><span style="color: #000000">__stl_threshold)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">__stl_threshold=const&nbsp;int&nbsp;16</span><span style="color: #008000"><br /><img id="Codehighlighter1_175_553_Open_Image" onclick="this.style.display='none'; Codehighlighter1_175_553_Open_Text.style.display='none'; Codehighlighter1_175_553_Closed_Image.style.display='inline'; Codehighlighter1_175_553_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_175_553_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_175_553_Closed_Text.style.display='none'; Codehighlighter1_175_553_Open_Image.style.display='inline'; Codehighlighter1_175_553_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_175_553_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_175_553_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(depth_limit</span><span style="color: #000000">==</span><span style="color: #000000">0</span><span style="color: #000000">)<br /><img id="Codehighlighter1_200_264_Open_Image" onclick="this.style.display='none'; Codehighlighter1_200_264_Open_Text.style.display='none'; Codehighlighter1_200_264_Closed_Image.style.display='inline'; Codehighlighter1_200_264_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_200_264_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_200_264_Closed_Text.style.display='none'; Codehighlighter1_200_264_Open_Image.style.display='inline'; Codehighlighter1_200_264_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_200_264_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_200_264_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;partial_sort(first,&nbsp;last,&nbsp;last);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">改用heapsort</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">--</span><span style="color: #000000">depth_limit;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RandomAccessIterator&nbsp;cut&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;__unguarded_partition(first,&nbsp;last,&nbsp;T(__median(</span><span style="color: #000000">*</span><span style="color: #000000">first,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(first</span><span style="color: #000000">+</span><span style="color: #000000">(last</span><span style="color: #000000">-</span><span style="color: #000000">first)</span><span style="color: #000000">/</span><span style="color: #000000">2</span><span style="color: #000000">,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">(last</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">)))));<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">cur为三点中值法求出来的pivot<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">右半段递归</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__introsort_loop(cut,&nbsp;last,&nbsp;value_type(first),&nbsp;depth_limit);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last</span><span style="color: #000000">=</span><span style="color: #000000">cut;</span><span style="color: #008000">//</span><span style="color: #008000">定位到左半段再递归处理(左右共用一个depth_limit)</span><span style="color: #008000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />&nbsp;&nbsp;&nbsp;分割方法：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">RandomAccessIterator&nbsp;__unguarded_partition(RandomAccessIterator&nbsp;first,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;RandomAccessIterator&nbsp;last,<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" />&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;T&nbsp;pivot)<br /><img id="Codehighlighter1_133_299_Open_Image" onclick="this.style.display='none'; Codehighlighter1_133_299_Open_Text.style.display='none'; Codehighlighter1_133_299_Closed_Image.style.display='inline'; Codehighlighter1_133_299_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_133_299_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_133_299_Closed_Text.style.display='none'; Codehighlighter1_133_299_Open_Image.style.display='inline'; Codehighlighter1_133_299_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_133_299_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_133_299_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(</span><span style="color: #0000ff">true</span><span style="color: #000000">)<br /><img id="Codehighlighter1_149_297_Open_Image" onclick="this.style.display='none'; Codehighlighter1_149_297_Open_Text.style.display='none'; Codehighlighter1_149_297_Closed_Image.style.display='inline'; Codehighlighter1_149_297_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_149_297_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_149_297_Closed_Text.style.display='none'; Codehighlighter1_149_297_Open_Image.style.display='inline'; Codehighlighter1_149_297_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_149_297_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_149_297_Open_Text"><span style="color: #000000">{<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(</span><span style="color: #000000">*</span><span style="color: #000000">first&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;pivot)&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">--</span><span style="color: #000000">last;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(pivot&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">last)&nbsp;</span><span style="color: #000000">--</span><span style="color: #000000">last;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">!</span><span style="color: #000000">(first</span><span style="color: #000000">&lt;</span><span style="color: #000000">last))&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter_swap(first,&nbsp;last);<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">first;<br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br /><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />&nbsp;&nbsp;&nbsp;在上述步骤做完以后，变将区间内元素分成了多个元素个数少于16的子序列，这个时候就进入到母函数，然后进行最后的插入排序。<br />&nbsp;&nbsp;&nbsp;SGI STL的最后插入排序是将其分成两部分：前一部分直接调用插入排序。后一部分再重写的一段插入排序（为什么这样做？）。<img src ="http://www.cppblog.com/dead-horse/aggbug/118017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/dead-horse/" target="_blank">dead_horse</a> 2011-06-08 01:06 <a href="http://www.cppblog.com/dead-horse/archive/2011/06/08/118017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>