﻿<?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++博客-金庆的专栏-随笔分类-5. 软工与管理</title><link>http://www.cppblog.com/jinq0123/category/5140.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 24 Apr 2022 06:08:58 GMT</lastBuildDate><pubDate>Sun, 24 Apr 2022 06:08:58 GMT</pubDate><ttl>60</ttl><item><title>TortoiseGit is OK but GitExtensions fails</title><link>http://www.cppblog.com/jinq0123/archive/2022/04/24/229292.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sun, 24 Apr 2022 06:01:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2022/04/24/229292.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/229292.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2022/04/24/229292.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/229292.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/229292.html</trackback:ping><description><![CDATA[    <h1 id="tortoisegit-is-ok-but-gitextensions-fails">TortoiseGit is OK but GitExtensions fails</h1>
    <p>GitExtensions and Git fail:</p>
    <pre>
      <code>"git" pull --progress "origin"
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Done
Press Enter or Esc to exit...
</code>
    </pre>
    <p>But TortoiseGit is OK.</p>
    <pre>
      <code>git.exe pull --progress -v --no-rebase "origin"
From github.com:jinq0123/recastnavigation
= [up to date]      master      -&gt; origin/master
= [up to date]      release-2.0 -&gt; origin/release-2.0
Already up to date.
</code>
    </pre>
    <p>
      <code>ssh -T</code> shows that the reason is there is no id files:</p>
    <pre>
      <code>PS d:\github&gt; ssh -vT git@github.com
OpenSSH_for_Windows
debug1: Connecting to github.com [20.205.243.166] port 22.
debug1: Connection established.
debug1: identity file C:\\Users\\jinqing/.ssh/id_rsa type -1
debug1: identity file C:\\Users\\jinqing/.ssh/id_xmss-cert type -1
debug1: Authenticating to github.com:22 as 'git'
debug1: Host 'github.com' is known and matches the ED25519 host key.
debug1: Found key in C:\\Users\\jinqing/.ssh/known_hosts:2
debug1: Will attempt key: C:\\Users\\jinqing/.ssh/id_rsa
debug1: Will attempt key: C:\\Users\\jinqing/.ssh/id_xmss
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Trying private key: C:\\Users\\jinqing/.ssh/id_rsa
debug1: Trying private key: C:\\Users\\jinqing/.ssh/id_xmss
debug1: No more authentication methods to try.
git@github.com: Permission denied (publickey).
PS d:\github&gt;
</code>
    </pre>
    <p>Copy my RSA key file rsa.ppk that TortoiseGit uses as ~/.ssh/id_rsa:</p>
    <pre>
      <code>PS D:\jinqing\github_jinq\recastnavigation&gt; ssh -T git@github.com
Load key "C:\\Users\\jinqing/.ssh/id_rsa": invalid format
git@github.com: Permission denied (publickey).
PS D:\jinqing\github_jinq\recastnavigation&gt;
</code>
    </pre>
    <p>Open TortoiseGit/bin/puttygen.exe, load rsa.ppk, then Convensionis-&gt;Export OpenSSH key as ~/.ssh/id_rsa:</p>
    <pre>
      <code>PS D:\jinqing\github_jinq\recastnavigation&gt; ssh -T git@github.com
Hi jinq0123! You've successfully authenticated, ...
</code>
    </pre>
    <p>id_rsa begins with:</p>
    <pre>
      <code>-----BEGIN RSA PRIVATE KEY-----
</code>
    </pre>
<img src ="http://www.cppblog.com/jinq0123/aggbug/229292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2022-04-24 14:01 <a href="http://www.cppblog.com/jinq0123/archive/2022/04/24/229292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>命名</title><link>http://www.cppblog.com/jinq0123/archive/2020/12/31/217558.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 31 Dec 2020 01:45:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2020/12/31/217558.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/217558.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2020/12/31/217558.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/217558.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/217558.html</trackback:ping><description><![CDATA[# 命名<br /><br />摘自：[警惕软件复杂度困局][1]<br /><br />软件中的API、方法、变量的命名，对于理解代码的逻辑、范围非常重要，也是设计者清晰传达意图的关键。<br />然而，在很多的项目里我们没有给Naming /命名足够的重视。<br /><br />我们的代码一般会和一些项目关联，但是需要注意的是项目是抽象的，而代码是具体的。<br />项目或者产品可以随意一些命名，如阿里云喜欢用中国古代神话（飞天、伏羲、女娲）命名系统，<br />K8s也是来自于希腊神话，这些都没有问题。<br />而代码中的API、变量、方法不能这样命名。<br /><br />一个不好的例子是前一段我们的Cluster API 被命名为Trident API（三叉戟），<br />设想一下代码中的对象叫Trident时，我们如何理解在这个对象应该具备的行为？<br />再对比一下K8s中的资源：Pod, ReplicaSet, Service, ClusterIP，<br />我们会注意到都是清晰、简单、直接符合其对象特征的命名。名实相符可以很大程度上降低理解该对象的成本。<br /><br />有人说&#8220;Naming is the most difficult part of software engineering&#8221;，<br />或许也不完全是个玩笑话：Naming的难度在于对于模型的深入思考和抽象，而这往往确实是很难的。<br /><br />需要注意的是：<br /><br />（a）Intention vs what it is<br /><br />需要避免用&#8220;是什么&#8221;来命名，要用&#8220;for what / intention&#8221;。&#8220;是什么&#8221;来命名是会很容易将实现细节。<br />比如我们用 LeakedBarrel做rate limiting，这个类最好叫 RateLimiter，而不是LeakedBarrel：<br />前者定义了意图（做什么的），后者 描述了具体实现，而具体实现可能会变化。<br />再比如 Cache vs FixedSizeHashMap，前者也是更好的命名。<br /><br />（b）命名需要符合当前抽象的层级<br /><br />首先我们软件需要始终有清晰的抽象和分层。<br />事实上我们Naming时遇到困难，很多就是因为软件已经缺乏明确的抽象和分层带来的表象而已。<br /><br /><br />[1]https://mp.weixin.qq.com/s?__biz=MzIzOTU0NTQ0MA==&amp;mid=2247498895&amp;idx=1&amp;sn=35b1d00e367c18c3d4ed7d4b15b38996&amp;chksm=e92ac180de5d4896fd5d789ffbe8c963986717b634f2dac09821c2b3ab2270a42f4a1c006ff5&amp;scene=21#wechat_redirect<img src ="http://www.cppblog.com/jinq0123/aggbug/217558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2020-12-31 09:45 <a href="http://www.cppblog.com/jinq0123/archive/2020/12/31/217558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN重命名时不要更改内容</title><link>http://www.cppblog.com/jinq0123/archive/2019/09/20/216848.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 20 Sep 2019 06:45:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2019/09/20/216848.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/216848.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2019/09/20/216848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/216848.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/216848.html</trackback:ping><description><![CDATA[SVN重命名时不要更改内容<br /><br />(金庆的专栏 2019.9)<br /><br />svn rename 某个文件并更改内容后提交，历史就会丢失。<br />如果 svn rename 后不改内容，立即提交，就可以延续原有历史。<br />所以改名这样的操作应该独立提交一次。<br /><br />git 改名就强大多了，会比较内容确定其原来的文件。但更改太多也会判断出错。<br /><img src ="http://www.cppblog.com/jinq0123/aggbug/216848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2019-09-20 14:45 <a href="http://www.cppblog.com/jinq0123/archive/2019/09/20/216848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>删除隐性的git submodule</title><link>http://www.cppblog.com/jinq0123/archive/2018/08/30/215889.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 30 Aug 2018 02:58:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2018/08/30/215889.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/215889.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2018/08/30/215889.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/215889.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/215889.html</trackback:ping><description><![CDATA[<div>删除隐性的git submodule<br /><br />(金庆的专栏 2018.8)<br /><br />正常的submodule会在 .gitmodule 文件中，TortoiseGit 会有 Submodule Update 菜单。<br />还有一种隐性的 submodule, .gitmodule 文件中看不到它，无法 update.<br />golang开发中的vendor目录下经常会不小心添加一个带 .git 的目录，就变成了一个假的submodule.<br />用 Repo-browser 看这个目录是个submodule链接, clone 出来就只有一个空目录。<br /><br />删除这个submodule不能用 git delete, 提交时会报错：<br /><br /><span style="color: #0000ff;">git.exe add -f [...]</span><br /><br /><span style="color: #0000ff;">fatal: pathspec 'src/vendor/github.com/grpc-ecosystem/grpc-opentracing' did not match any files</span><br /><br /><span style="color: #0000ff;">git did not exit cleanly (exit code 128)</span><br /><br />git delete 父目录也无法提交。<br /><br />但是可以直接删除（不用git delete）, 然后提交并Push. 好像只有这个办法。<br /><br /><br /><br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/215889.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2018-08-30 10:58 <a href="http://www.cppblog.com/jinq0123/archive/2018/08/30/215889.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用docker stack开启redis集群</title><link>http://www.cppblog.com/jinq0123/archive/2017/10/26/215308.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 26 Oct 2017 04:08:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2017/10/26/215308.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/215308.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2017/10/26/215308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/215308.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/215308.html</trackback:ping><description><![CDATA[<div>用docker stack开启redis集群<br /><br />(金庆的专栏 2017.10)<br /><br />有5个docker swarm节点，开启redis cluster.<br />每个机器上开2个redis节点，共10个redis节点。<br />采用官方的redis:alpine镜像。<br /><br />docker-stack.yml 如下：<br /><br /><span style="color: #800000; font-family: Courier;">version: "3"</span><br /><span style="color: #800000; font-family: Courier;">services:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp; redis001:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; image: redis:alpine</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; volumes:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - /home/redis/001/data:/data</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - /home/redis/001/conf:/conf</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; command: redis-server --appendonly yes --cluster-enabled yes --cluster-config-file /conf/nodes.conf --cluster-announce-ip 10.240.79.8 --cluster-announce-port 7001 --cluster-announce-bus-port 17001</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; ports:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - "7001:6379"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - "17001:16379"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; networks:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - redisnet</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; deploy:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; placement:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constraints:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - node.hostname == host-10-240-79-8</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp; redis002:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; image: redis:alpine</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; volumes:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - /home/redis/002/data:/data</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - /home/redis/002/conf:/conf</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; command: redis-server --appendonly yes --cluster-enabled yes --cluster-config-file /conf/nodes.conf --cluster-announce-ip 10.240.79.9 --cluster-announce-port 7002 --cluster-announce-bus-port 17002</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; ports:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - "7002:6379"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - "17002:16379"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; networks:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - redisnet</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; deploy:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; placement:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constraints:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - node.hostname == host-10-240-79-9</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp; redis003:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp; ...</span><br /><span style="color: #800000; font-family: Courier;">&nbsp; redis010:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; ...</span><br />&nbsp; <br /><span style="color: #800000; font-family: Courier;">networks:</span><br /><span style="color: #800000; font-family: Courier;">&nbsp; redisnet:</span><br /><br />数据保存文件在 /home/redis/001/data<br />集群配置文件将保存到 /home/redis/001/conf/nodes.conf &nbsp;<br />各机器上目录需要预先创建，不然docker开启失败。<br />并且需要设置目录权限，不然报"Permission denied".<br />redis-server以用户uid=100(redis)运行，所以<br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; chown -R 100 /home/redis/</span><br /><br />启动redis服务栈:<br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; docker stack deploy -c docker-stack.yml redis</span><br /><br />redis-server启动后，运行 redis-trib.rb 来组建 redis cluster:<br /><br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; docker run --rm -it inem0o/redis-trib create --replicas 1 10.240.79.8:7001 10.240.79.9:7002 ... 10.240.79.12:7010</span><br /><br />注意 inem0o/redis-trib 的说明中，命令示例缺少 "-it", 会报错退出：<br /><span style="color: #0000ff;">Can I set the above configuration? (type 'yes' to accept): : undefined method `chomp' for nil:NilClass (NoMethodError)</span><br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from /usr/bin/redis-trib:1295:in `create_cluster_cmd'</span><br /><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; from /usr/bin/redis-trib:1701:in `&lt;main&gt;'</span><br /><br />运行 redis-cli 测试，"-c" 参数表示集群，可连接任意机器的7001-7010任意端口：<br /><span style="color: #0000ff;">[root@host-10-240-79-9 ~]# docker run -it --rm redis:alpine redis-cli -h 10.240.79.8 -p 7006 -c</span><br /><span style="color: #0000ff;">10.240.79.8:7006&gt; get a</span><br /><span style="color: #0000ff;">-&gt; Redirected to slot [15495] located at 10.240.79.10:7003</span><br /><span style="color: #0000ff;">(nil)</span><br /><br />用swarm mode开启redis服务比较方便。<br />但是出于性能考虑，应该禁用 swarm 的NAT转发和负载均衡。<br />研究了下，暂时还没学会。<br /><br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/215308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2017-10-26 12:08 <a href="http://www.cppblog.com/jinq0123/archive/2017/10/26/215308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lua区分公有私有接口</title><link>http://www.cppblog.com/jinq0123/archive/2017/08/18/215169.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 18 Aug 2017 10:51:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2017/08/18/215169.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/215169.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2017/08/18/215169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/215169.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/215169.html</trackback:ping><description><![CDATA[<div>Lua区分公有私有接口<br /><br />(金庆的专栏 2017.8)<br /><br />Lua语言没有提供public, private的概念，所有模块或类中的接口都是公有的。<br /><br />可以通过注释来区分公有私有接口。<br /><br />ldoc 提供了一个 @section 标签，可用作此功能<br /><br /><span style="color: #800000; font-family: Courier;">--- Test module.</span><br /><span style="color: #800000; font-family: Courier;">-- @module my_mod</span><br /><span style="color: #800000; font-family: Courier;">local M = {}</span><br /><br /><span style="color: #800000; font-family: Courier;">--- Public functions</span><br /><span style="color: #800000; font-family: Courier;">-- @section public</span><br /><br /><span style="color: #800000; font-family: Courier;">--- foo.</span><br /><span style="color: #800000; font-family: Courier;">-- @int a a test input</span><br /><span style="color: #800000; font-family: Courier;">-- @treturn int result</span><br /><span style="color: #800000; font-family: Courier;">function M.foo(a)</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; return a + 1</span><br /><span style="color: #800000; font-family: Courier;">end</span><br /><br /><span style="color: #800000; font-family: Courier;">--- Private functions</span><br /><span style="color: #800000; font-family: Courier;">-- @section private</span><br /><br /><span style="color: #800000; font-family: Courier;">--- goo.</span><br /><span style="color: #800000; font-family: Courier;">-- @int a a test input</span><br /><span style="color: #800000; font-family: Courier;">-- @treturn int result</span><br /><span style="color: #800000; font-family: Courier;">function M.goo(a)</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp; return a + 2</span><br /><span style="color: #800000; font-family: Courier;">end</span><br /><br /><span style="color: #800000; font-family: Courier;">return M</span><br /><br />ldoc 生成文档后是这样的：</div><img src="http://www.cppblog.com/images/cppblog_com/jinq0123/my_mod.png" alt="" width="395" height="698" /><img src ="http://www.cppblog.com/jinq0123/aggbug/215169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2017-08-18 18:51 <a href="http://www.cppblog.com/jinq0123/archive/2017/08/18/215169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lua53 premake</title><link>http://www.cppblog.com/jinq0123/archive/2017/02/18/214686.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 18 Feb 2017 14:18:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2017/02/18/214686.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/214686.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2017/02/18/214686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/214686.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/214686.html</trackback:ping><description><![CDATA[<div>Lua53 premake<br /><br />(金庆的专栏 2017.2)<br /><br />参考：用premake5创建lua532工程 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http://blog.csdn.net/jq0123/article/details/51242780<br /><br /><span style="color: #800000; font-family: Courier;">-- premake5.lua</span><br /><span style="color: #800000; font-family: Courier;">--[[</span><br /><span style="color: #800000; font-family: Courier;">Usage examples: </span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; for windows: premake5.exe --os=windows vs2015</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; fot linux:&nbsp;&nbsp; premake5.exe --os=linux gmake</span><br /><span style="color: #800000; font-family: Courier;">]]</span><br /><br /><span style="color: #800000; font-family: Courier;">workspace "lua53"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; configurations { "Debug", "Release" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; targetdir "bin/%{cfg.buildcfg}"</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; language "C++"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; -- Force VS to compile as C++.</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; -- https://github.com/premake/premake-core/issues/142</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; filter "action:vs*"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildoptions "/TP"</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; filter "system:windows"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defines { "LUA_BUILD_AS_DLL" }</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; filter "configurations:Debug"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defines { "DEBUG" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flags { "Symbols" }</span><br /><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; filter "configurations:Release"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defines { "NDEBUG" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; optimize "On"</span><br /><br /><span style="color: #800000; font-family: Courier;">project "lua53"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; kind "ConsoleApp"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; files { "src/lua.c" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; links { "lua53_shared_lib" }&nbsp; &nbsp;</span><br /><br /><span style="color: #800000; font-family: Courier;">project "luac53"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; kind "ConsoleApp"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; files { "src/luac.c" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; links { "lua53_static_lib" }&nbsp; -- Link error on Windows if link lua53 shared lib.&nbsp; &nbsp;</span><br /><br /><span style="color: #800000; font-family: Courier;">project "lua53_shared_lib"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; kind "SharedLib"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; targetname "lua53"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; files { "src/*.h", "src/*.c" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; removefiles { "src/lua.c", "src/luac.c" }</span><br /><br /><span style="color: #800000; font-family: Courier;">project "lua53_static_lib"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; kind "StaticLib"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; targetname "lua53"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; filter "system:windows"</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; targetprefix "lib"&nbsp; -- liblua53.lib<br />&nbsp;&nbsp; filter {}<br /></span><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; files { "src/*.h", "src/*.c" }</span><br /><span style="color: #800000; font-family: Courier;">&nbsp;&nbsp; removefiles { "src/lua.c", "src/luac.c" }</span><br />&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />更改之处：<br />* VS强制按C++编译<br />* 创建动态库和静态库<br />* lua53.exe 链接动态库，luac53.exe 链接静态库<br /><div>&nbsp; 因为 luac53.exe 链接动态库缺3个函数未导出。<br />* 添加宏 LUA_BUILD_AS_DLL，不然 lua53.dll 不会生成 lua53.lib&nbsp; &nbsp;</div>&nbsp;</div><img src ="http://www.cppblog.com/jinq0123/aggbug/214686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2017-02-18 22:18 <a href="http://www.cppblog.com/jinq0123/archive/2017/02/18/214686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ejabberd开发和部署</title><link>http://www.cppblog.com/jinq0123/archive/2016/10/31/214369.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 31 Oct 2016 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2016/10/31/214369.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/214369.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2016/10/31/214369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/214369.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/214369.html</trackback:ping><description><![CDATA[<div><div id="article_content"> <p>ejabberd开发和部署</p><p><br /></p><p>(金庆的专栏 2016.10)</p><p><br /></p><p>搭建了自己的ejabberd集群，然后少量更改源码，实现定制的XMPP服务器。</p><p>从github fork ejabberd 库，定为 master 分支跟踪原始库 master 分支，版本升级时从原库合并一次。</p><p>从16.09版本分一个 dev 分支，自己的代码就在这个 dev 分支上写。</p><p>服务器从源码编译安装。</p><p>代码更改后，make install, 然后 ejabberd restart, 或者 ejabberd update all.</p><p>如果有配置更改，则还要更改 /etc/ejabberd/ejabberd.yml.</p><p>未来主库版本升级后，可重新开个dev2分支，将dev的更改合并到dev2.<br /></p><p><br /></p>    </div></div><img src ="http://www.cppblog.com/jinq0123/aggbug/214369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2016-10-31 17:13 <a href="http://www.cppblog.com/jinq0123/archive/2016/10/31/214369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows运行GitStats</title><link>http://www.cppblog.com/jinq0123/archive/2016/05/31/213614.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 31 May 2016 03:51:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2016/05/31/213614.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/213614.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2016/05/31/213614.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/213614.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/213614.html</trackback:ping><description><![CDATA[<div>Windows运行GitStats<br /><br />(金庆的专栏)<br /><br />GitStats - git history statistics generator<br />http://gitstats.sourceforge.net/<br /><br />GitStats是git统计工具。<br />只是一个python脚本，使用 gnuplot 画图。<br />Windows下运行需要安装 python, git, gnuplot.<br />需要设置path, 使这些工具可以在命令行中使用。<br />还需要用到 wc 工具，我的 &#8220;Git for Windows&#8221; 正好有个 sh.exe, 其中带了 wc,<br />所以打开 git 的 sh.exe, 进入 GitStats 目录，按说明运行脚本：<br /><br /><span style="color: #000080;">jinqing@ZT-2203857 MINGW64 /e/git/gitstats (master)</span><br /><span style="color: #000080;">$ python gitstats /e/server_master /e/temp/server_master</span><br /><br />会出现 import gitstats 错误，需要先把 gitstats 复制成 gitstats.py.<br /><br />结果为 index.html。<br /><br />因为无法过滤文件，所以统计中都是些其他文件，<br />例如无法将Lua文件排除，无法排除依赖库。<br /><br />提供的参数有如下:<br /><span style="color: #000080;">jinqing@ZT-2203857 MINGW64 /e/git/gitstats (master)</span><br /><span style="color: #000080;">$ python gitstats</span><br /><br /><span style="color: #000080;">Usage: gitstats [options] &lt;gitpath..&gt; &lt;outputpath&gt;</span><br /><br /><span style="color: #000080;">Options:</span><br /><span style="color: #000080;">-c key=value&nbsp;&nbsp;&nbsp;&nbsp; Override configuration value</span><br /><br /><span style="color: #000080;">Default config values:</span><br /><span style="color: #000080;">{'project_name': '', 'processes': 8, 'max_domains': 10, 'commit_begin': '', 'max</span><br /><span style="color: #000080;">_ext_length': 10, 'commit_end': 'HEAD', 'linear_linestats': 1, 'style': 'gitstat</span><br /><span style="color: #000080;">s.css', 'max_authors': 20, 'authors_top': 5, 'start_date': ''}</span><br /><br /><span style="color: #000080;">Please see the manual page for more details.</span><br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/213614.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2016-05-31 11:51 <a href="http://www.cppblog.com/jinq0123/archive/2016/05/31/213614.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> CMake搜索Boost1.57失败及解决</title><link>http://www.cppblog.com/jinq0123/archive/2015/01/20/209584.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 20 Jan 2015 04:18:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2015/01/20/209584.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/209584.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2015/01/20/209584.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/209584.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/209584.html</trackback:ping><description><![CDATA[<div><div id="article_content"> <p>CMake更新到3.1.0，Boost更新到1.57，结果CMake搜索Boost失败：</p><p><span style="color:#FF0000;">&nbsp; Unable to find the Boost header files.&nbsp; Please set BOOST_ROOT to the root<br />&nbsp; directory containing Boost or BOOST_INCLUDEDIR to the directory containing<br />&nbsp; Boost's headers.<br /></span>&nbsp; <br />已设置环境变量 BOOST_ROOT = C:\Boost</p><p>查看 FindBoost.cmake 脚本，发现它仅搜索已知的版本，而最新版 1.57 还未添加：<br /></p><p><span style="color:#990000;">&nbsp; set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}<br />&nbsp;&nbsp;&nbsp; "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54"<br />&nbsp;&nbsp;&nbsp; "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51"<br />&nbsp;&nbsp;&nbsp; "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1"<br /><br /></span>添加 &#8220;1.57&#8221; 后即成功。</p><p>FindBoost.cmake 应该添加 Boost 未来版本才好。</p><p><br /></p> </div></div><img src ="http://www.cppblog.com/jinq0123/aggbug/209584.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2015-01-20 12:18 <a href="http://www.cppblog.com/jinq0123/archive/2015/01/20/209584.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CMake设置FOLDER失败及解决</title><link>http://www.cppblog.com/jinq0123/archive/2014/12/07/209051.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sun, 07 Dec 2014 15:11:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2014/12/07/209051.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/209051.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2014/12/07/209051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/209051.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/209051.html</trackback:ping><description><![CDATA[<div>CMake可以设置FOLDER属性，用来分目录组织VC中的多个工程。<br /><ul><li><strong><code>FOLDER</code></strong>: Set the folder name. Use to organize targets in an IDE.<br /><p>Targets  with no FOLDER property will appear as top level entities in IDEs like  Visual Studio. Targets with the same FOLDER property value will appear  next to each other in a folder of that name. To nest folders, use FOLDER  values such as 'GUI/Dialogs' with '/' characters separating folder  levels.</p></li></ul><p><br /></p><p>方法如下：</p><p><div><span style="color: #333300;">Add this to the top level CMakeLists.txt</span><br /><span style="color: #333300;">#Use solution folders.</span><br /><span style="color: #333300;">set_property(GLOBAL PROPERTY USE_FOLDERS ON)</span><br /><br /><span style="color: #333300;"># Then in some target add this to put the target in the Development folder.</span><br /><span style="color: #333300;">set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Development)</span></div><br /></p>不过VcExpress因为不支持工程目录，所以FOLDER属性无效。<p><br /></p><p>因为机器上同时安装了VC和VcExpress，CMake总是判断为Express版，所以FOLDER设置总是无效。</p><p>最终打开sln文件看到了头部的这行才找到问题原因：</p><p><span style="color:#660000;"># Visual C++ Express</span></p><p><br /></p><p>然后在CMake源码中找到了Express版本检测代码：</p><p><span style="font-family:Courier New;color:#660000;">&nbsp; this-&gt;ExpressEdition = cmSystemTools::ReadRegistryValue(<br />&nbsp;&nbsp;&nbsp; "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\14.0\\Setup\\VC;"<br />&nbsp;&nbsp;&nbsp; "ProductDir", vc14Express, cmSystemTools::KeyWOW64_32);<br /></span></p>删除该注册表项就不会被判为Express版了，FOLDER设置成功。</div><img src ="http://www.cppblog.com/jinq0123/aggbug/209051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2014-12-07 23:11 <a href="http://www.cppblog.com/jinq0123/archive/2014/12/07/209051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代码那些事之命名</title><link>http://www.cppblog.com/jinq0123/archive/2014/11/04/208774.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 04 Nov 2014 13:00:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2014/11/04/208774.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/208774.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2014/11/04/208774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/208774.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/208774.html</trackback:ping><description><![CDATA[<div><p>摘自：代码那些事之命名&#8203;&#8212;&#8212;《可读代码的艺术》读后感<br /></p><p>http://bj007.blog.51cto.com/1701577/1309002</p><h4><a name="t0"></a><span style="font-family:'宋体';font-size:16px;line-height:156%;">选择具体的词</span></h4><p style="text-indent:28px;"><span style="font-family:'宋体';">比如</span>GetPage<span style="font-family:'宋体';">函数命名中</span>Get<span style="font-family:'宋体';">就比较空泛，可能有几种情况，比如从文件读取、去远处获取、去数据库查询、或者就是简单地从返回成员变量，如果一切都是</span>Get<span style="font-family:'宋体';">就需要扒开具体实现才可能确定到底用哪种方式。如果我们可以选择更具体的词，比如文件读取用</span>Read<span style="font-family:'宋体';">或者</span>Load<span style="font-family:'宋体';">、远程获取用</span>Fetch<span style="font-family:'宋体';">、数据库查询用</span>Query<span style="font-family:'宋体';">、简单返回成员变量时候采用</span>Get<span style="font-family:'宋体';">，并且整个项目保持一致，可能仅仅看到名字就可以闪现出对应的场景。将信息塞进名字中的一部分就是选择很具体、避免空泛的一些词。</span></p><p style="text-indent:168px;"><br /></p><h4><a name="t1"></a><span style="font-family:'宋体';font-size:16px;line-height:156%;">避免误解。</span></h4><p style="text-indent:21px;"><span style="font-family:'宋体';">被误解是很受伤的一件事，但是我们的命名就尝尝别误解，而且还常常是整个意思反过来了。因此在检查名字的时候就是主动问下自己&#8220;别人对于这个名字是否有不同的解读？&#8221;。比如如下代码：</span></p><table width="100%" cellpadding="0" cellspacing="0"><tbody><tr><td><p style="text-indent:21px;">results = Database.all_objects.filter("year &lt;=  2011")</p></td></tr></tbody></table><p style="text-indent:21px;"><span style="font-family:'宋体';">其中，</span>results<span style="font-family:'宋体';">会包含什么呢？</span><span style="font-family:'宋体';">问题就出在</span>filter<span style="font-family:'宋体';">上，可能是过滤掉、也可能是过滤出。建议就是如果要过滤出，</span>select()<span style="font-family:'宋体';">会更好，如果要过滤掉，</span>exclude()会更好。</p><p><br /></p></div><img src ="http://www.cppblog.com/jinq0123/aggbug/208774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2014-11-04 21:00 <a href="http://www.cppblog.com/jinq0123/archive/2014/11/04/208774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TSVN客户端复制文件</title><link>http://www.cppblog.com/jinq0123/archive/2014/08/17/208041.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sun, 17 Aug 2014 01:44:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2014/08/17/208041.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/208041.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2014/08/17/208041.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/208041.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/208041.html</trackback:ping><description><![CDATA[<div><p>TSVN客户端复制文件</p><p><br /></p><p>代码重构中，可能需要将一个大文件拆分成2个小文件，同时要保证拆分后的小文件继承原来的SVN历史记录。<br /></p><p>TSVN客户端只有Rename功能，没有Copy功能。</p><p>可进入Browser界面，直接在服务器文件列表中复制，但是服务器端复制会产生一个版本，这个版本多半是无法构建的。</p><p>用Rename-Revert可在客户端产生文件复制，并保留历史记录。</p><p>1. Rename到新的文件。此时旧文件会被删除。</p><p>2. Revert被删除的文件。注意新增的文件不要Revert。之后旧文件被恢复。</p></div><img src ="http://www.cppblog.com/jinq0123/aggbug/208041.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2014-08-17 09:44 <a href="http://www.cppblog.com/jinq0123/archive/2014/08/17/208041.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CMake生成版本号</title><link>http://www.cppblog.com/jinq0123/archive/2012/08/15/187268.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 15 Aug 2012 04:30:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2012/08/15/187268.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/187268.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2012/08/15/187268.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/187268.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/187268.html</trackback:ping><description><![CDATA[<div>CMake生成版本号<br /><br />（金庆的专栏）<br /><br />原来的CMake需要用shell脚本生成SVN版本号，再作为cmake参数传入。<br /><br />CMake调用脚本示例：<br /><br /><span style="font-family:Courier New;color:#660000;">#!/bin/sh<br /># cmake.sh<br /><br />ServerCodeRoot=~/Code/Server<br />CodeRevNum=`svn info ${ServerCodeRoot} | grep Revision | awk -F' ' '{ print $2 }'`<br />cmake S{ServerCodeRoot} -DCMAKE_BUILD_TYPE=Release -DVERSION_REVISION=S{CodeRevNum}<br /></span><br />CMakeLists.txt中如下配置：<br /><span style="font-family:Courier New;color:#660000;">configure_file(<br />&nbsp; "Version.h.in"<br />&nbsp; "Version.h"<br />)</span><br /><br />Version.h.in如下：<br /><br /><span style="font-family:Courier New;color:#660000;">#include &lt;string&gt;<br />const std::string VERSION_MAJOY("1");<br />const std::string VERSION_MINOR("0");<br />const std::string VERSION_REVISION("@VERSION_REVISION@");<br /></span><br />Linux下执行cmake.sh会自动替换SVN版本号。<br /><br />现改为用FIND_PACKAGE(Subversion)方式，不必用shell脚本生成SVN版本号，<br />并且在Windows上也可以生成版本号, cmake调用时不必传VERSION_REVISION参数。<br /><br />CMakeLists.txt改为（参考了开源网游ryzom的CMake）：<br /><br /><span style="font-family:Courier New;color:#660000;">SET(ROOT_DIR ${PROJECT_SOURCE_DIR})<br />IF(EXISTS "${ROOT_DIR}/.svn/")<br />&nbsp; FIND_PACKAGE(Subversion)<br /><br />&nbsp; IF(SUBVERSION_FOUND)<br />&nbsp;&nbsp;&nbsp; Subversion_WC_INFO(${ROOT_DIR} Project)<br />&nbsp;&nbsp;&nbsp; SET(VERSION_REVISION ${Project_WC_REVISION})<br />&nbsp; ENDIF(SUBVERSION_FOUND)<br />ENDIF(EXISTS "${ROOT_DIR}/.svn/")<br /><br />CONFIGURE_FILE(<br />&nbsp; "Version.h.in"<br />&nbsp; "Version.h"<br />)</span><br /><br />如果不是SVN, 而是用Hg, 可用如下脚本：<br /><span style="font-family:Courier New;color:#660000;">IF(EXISTS "${ROOT_DIR}/.hg/")<br />&nbsp; FIND_PACKAGE(Mercurial)<br /><br />&nbsp; IF(MERCURIAL_FOUND)<br />&nbsp;&nbsp;&nbsp; Mercurial_WC_INFO(${ROOT_DIR} ER)<br />&nbsp;&nbsp;&nbsp; SET(REVISION ${ER_WC_REVISION})<br />&nbsp;&nbsp;&nbsp; SET(CHANGESET ${ER_WC_CHANGESET})<br />&nbsp;&nbsp;&nbsp; SET(BRANCH ${ER_WC_BRANCH})<br />&nbsp; ENDIF(MERCURIAL_FOUND)<br />ENDIF(EXISTS "${ROOT_DIR}/.hg/")<br /></span></div><img src ="http://www.cppblog.com/jinq0123/aggbug/187268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2012-08-15 12:30 <a href="http://www.cppblog.com/jinq0123/archive/2012/08/15/187268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CMake区分debug、release版本</title><link>http://www.cppblog.com/jinq0123/archive/2012/03/27/169143.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 27 Mar 2012 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2012/03/27/169143.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/169143.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2012/03/27/169143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/169143.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/169143.html</trackback:ping><description><![CDATA[<div><p>摘自： http://www.cppblog.com/tx7do/archive/2010/08/19/124000.html<br /></p><p><br /></p><p>建立debug/release两目录，分别在其中执行cmake -DCMAKE_BUILD_TYPE=Debug（或Release），需要编译不同版本时进入不同目录执行make即可；</p><p><strong>Debug版会使用参数-g；Release版使用-O3 &#8211;DNDEBUG</strong></p></div><img src ="http://www.cppblog.com/jinq0123/aggbug/169143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2012-03-27 13:56 <a href="http://www.cppblog.com/jinq0123/archive/2012/03/27/169143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库的版本控制是必须的</title><link>http://www.cppblog.com/jinq0123/archive/2012/03/08/167395.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 08 Mar 2012 06:17:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2012/03/08/167395.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/167395.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2012/03/08/167395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/167395.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/167395.html</trackback:ping><description><![CDATA[<div><div><p>摘自：程序员开发利器：源代码管理的十条建议</p><p>（&nbsp;http://tech.it168.com/a2012/0307/1321/000001321198_1.shtml ）</p></div><br />数据库的版本控制是必须的<br /><br />这是有很多人想做，但是觉得很困难而做不到的一点。这里的问题是，很多应用没有数据库根本无法运行。所以如果你不把数据库加入版本控制的话，你的应用是不完整的。<br /><br />大部分的版本控制系统只针对文件系统工作，例如 HTML，CSS，图片，配置文件等等任何保存在文件系统中的东西。但是对于数据库中的数据却无能为力。<br /><br />不过现在也有一些数据库版本控制工具，例如 Red Gate 出品的 SQL Source Control。关于这个工具我曾经写过很详细的文章 Rocking your SQL Sourc Control world with Red Gate，我在这里就不赘述了。总之，数据库的版本控制也很容易了!</div><img src ="http://www.cppblog.com/jinq0123/aggbug/167395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2012-03-08 14:17 <a href="http://www.cppblog.com/jinq0123/archive/2012/03/08/167395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL无法本地连接</title><link>http://www.cppblog.com/jinq0123/archive/2011/10/21/158831.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 21 Oct 2011 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2011/10/21/158831.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/158831.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2011/10/21/158831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/158831.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/158831.html</trackback:ping><description><![CDATA[<div>MySQL无法本地连接<br /><br />（金庆的专栏）<br /><br />Linux重启后，发现不知怎么的MySQL无法本地连接。<br /><br />结果phpMyAdmin, Zentao都无法正常工作了。<br /><br />远程的连接用了TCP是正常的，本地连接用了本地socket, 有问题。<br /><br />本地运行mysql客户端会报错：<br />Can&#8217;t connect to local MySQL server through socket &#8216;/var/lib/mysql/mysql.sock&#8217; (2)<br /><br />重启mysql服务也报错：<br /># service mysql restart<br />MySQL server PID file could not be found! <br />Starting MySQL... ...The server quit without updating PID file (/var/lib/mysql/localhost/localdomain.pid)<br /><br />该.pid文件不存在。所以无法关闭mysql. 正在运行的mysql服务一直无法关闭。<br /><br />参考：http://zhujipi.com/vps/109.html<br />说明，Mysql的进程卡死了，这时用就要把这些卡死的进程都关闭。<br /><br />mysql服务重启成功后恢复正常。<br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/158831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2011-10-21 16:27 <a href="http://www.cppblog.com/jinq0123/archive/2011/10/21/158831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设定“svn:needs-lock”属性</title><link>http://www.cppblog.com/jinq0123/archive/2011/10/12/158128.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 12 Oct 2011 06:33:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2011/10/12/158128.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/158128.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2011/10/12/158128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/158128.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/158128.html</trackback:ping><description><![CDATA[<div><p>摘自： http://www.cnblogs.com/LittleFox/archive/2009/04/08/1431781.html</p><p><br /></p><p><span id="comment_body_1498206">设定&#8220;svn:needs-lock&#8221;属性<br />使用命令行锁定&#8220;介绍.doc&#8221;：<br /><br />svn propset svn:needs-lock 'x' 介绍.doc<br /><br />运 行这个命令后，&#8220;介绍.doc&#8221;就已经是设置了&#8220;svn:needs-lock &#8221;，但为了使之生效还要运行&#8220;svn  commit&#8221;，之后其他用户update的时候就会发现这个文件已经是只读的了。需要注意的是我们设置的属性值是&#8220;x&#8221;，实际上任意值都可以，  Subversion会忽略其内容。<br /><br />使用TortoiseSVN设定属性也很简单：<br /><br />&#8220;介绍.doc&#8221;右键选中-  &gt;属性-&gt;Subversion选项夹-&gt;properties-&gt;add，然后在弹出的窗口中的property  name选择&#8220;svn:needs-lock&#8221;，值任意，然后选择OK。之后再提交&#8220;介绍.doc&#8221;即可。</span><br /></p></div><img src ="http://www.cppblog.com/jinq0123/aggbug/158128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2011-10-12 14:33 <a href="http://www.cppblog.com/jinq0123/archive/2011/10/12/158128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>给VS2005的编辑器添加右边界线</title><link>http://www.cppblog.com/jinq0123/archive/2011/09/19/156235.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 19 Sep 2011 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2011/09/19/156235.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/156235.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2011/09/19/156235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/156235.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/156235.html</trackback:ping><description><![CDATA[<div>
<p>转自： http://www.cnblogs.com/duzouzhe/archive/2009/08/05/1539292.html</p>
<p><br />
</p>
<p>&nbsp;</p>
<div>好的代码风格是生成高质量软件的基础，其中有一点就是代码的每行不能太长，一般建议每行不超过80个字符。<br />
VS2005里面有个隐藏的功能是可以设置编辑器的边界线。创建一个VS2005_Guideline.reg文件，内容为：<br />
<code><br />
Windows Registry Editor Version 5.00<br />
［HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\Text Editor］<br />
"Guides"="ＲＧＢ(128,0,0) 80, 120"<br />
</code><br />
然后将其导入注册表，重启VS2005后就看到我们创建的两条边界线，分别在80和120的地方（如果只需创建一条边界线，可以把",120"去掉）。使用上面的小技巧我们在写代码时就可以很直观地看到代码是否超过每行规定的边界了。</div>
<br />
<div></div>
<div></div>
</div><img src ="http://www.cppblog.com/jinq0123/aggbug/156235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2011-09-19 15:53 <a href="http://www.cppblog.com/jinq0123/archive/2011/09/19/156235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>svn日志乱码</title><link>http://www.cppblog.com/jinq0123/archive/2011/08/08/152762.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 08 Aug 2011 03:12:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2011/08/08/152762.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/152762.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2011/08/08/152762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/152762.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/152762.html</trackback:ping><description><![CDATA[<div>svn日志乱码<br /><br />（金庆的专栏）<br /><br />Windows上用TortoiseSVN提交, 在Linux上查看日志时显示的是乱码.<br />中文字符变成了一个问号和一个8进制数, 如: ?\227。<br /><br />将日志输出为xml: svn log -r 123456 --xml &gt; log.xml<br />然后用iconv手工转成GB2312显示:<br />iconv -f utf8 -t GB2312 log.xml<br />就可以发现iconv报告: 未知 nn 处的非法输入序列.<br /><br />此处是一个横杠, "&#8212;", GB2312码为0xa1aa, utf8码为0xe28094,<br />iconv将svn日志uft8转GB2312时失败, 所以才显示出乱码.<br /><br />iconv 可以将 0xa1aa 转成 0xe28094, 但是不能反向转.<br />还有一个稍短点的横杠, 0xe28095, GB2312码为0xa844,<br />iconv可以从GB2312转成utf8, 但是utf8转GB2312失败.<br /><br />不知有没有办法让svn忽略无法转换的字符? 这样整条日志还是可以看到.<br /><br />在linux上svn直接提交的长横杠显示是正常的,<br />GB码是0xa1aa, xml日志中utf8码是0xe28095.<br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/152762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2011-08-08 11:12 <a href="http://www.cppblog.com/jinq0123/archive/2011/08/08/152762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游更新安全第一</title><link>http://www.cppblog.com/jinq0123/archive/2010/05/19/115822.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 19 May 2010 09:51:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/05/19/115822.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/115822.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/05/19/115822.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/115822.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/115822.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 对于已经上线的网游服务器，更改代码时要把安全性放在第一位，避免引入错误。<br>添加某个功能或修正某一个错误时，应该将变更的范围尽量控制在最小范围。<br>尽量不要造成对其他现有功能的影响。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/05/19/115822.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/115822.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-05-19 17:51 <a href="http://www.cppblog.com/jinq0123/archive/2010/05/19/115822.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++测试框架的选择</title><link>http://www.cppblog.com/jinq0123/archive/2010/04/13/112430.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 13 Apr 2010 02:53:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/04/13/112430.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/112430.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/04/13/112430.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/112430.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/112430.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文以表格形式总结了 “Exploring the C++ Unit Testing Framework Jungle” ( http://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle  ) 一文对各种单元测试框架的比较，并添加了原文所还没有加入的Google Test. 并添加了另一项特性比较，即对Mock对象的支持。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/04/13/112430.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/112430.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-04-13 10:53 <a href="http://www.cppblog.com/jinq0123/archive/2010/04/13/112430.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>圈复杂度和代码覆盖率</title><link>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 09 Mar 2010 01:42:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/109242.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/109242.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/109242.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 100%代码覆盖率的单元测试并不代表是足够的测试，下面是一个例子：&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/109242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-03-09 09:42 <a href="http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何保持软件开发团队的稳定性</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 20 Jan 2010 05:18:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/106061.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/106061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/106061.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 保持团队的稳定性说来容易，其实对于每一个优秀的研发经理和公司CEO都非常具有挑战性，尤其是员工很多时候并不能意识到这一点和理解领导层的压力。就好比单身汉不能理解父亲的心情一样。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/106061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-20 13:18 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>随机数生成器应该如何单元测试？</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 09 Jan 2010 04:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/105236.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/105236.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/105236.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有个随机数生成函数，按以下分布随机生成1个1-100的整数：90%概率为1-50，10%概率为51-100.<br>单元测试应该如何进行呢？<br>生成10000个数然后计算分布比例应该可以，只要在90%上下就算通过。<br>但是仍有极小可能产生测试失败的可能。<br>如何做一个具有确定性结论的测试用例？ &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/105236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-09 12:24 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你愿意别人更改你的代码吗?</title><link>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 21 Nov 2009 04:55:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/101550.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/101550.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/101550.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 看到怪盗KID的文章<br>( http://hi.baidu.com/kidcdf/blog/item/2cefd85c9d13f449fbf2c09f.html )<br>最后一句: 没有一个人喜欢看着自己辛辛苦苦做的东西被反复删掉重写.<br><br>个人觉得别人更改自己写的代码是我乐意接受的. 不知大家有什么想法?<br><br>你愿意别人更改你的代码吗?<br>A) 代码一旦提交, 就是大家公有的代码, 无所谓谁改谁的代码.<br>B) 很乐意有人愿意更改自己的代码.<br>C) 绝不允许别人更改自己的代码.<br>D) 看到自己的代码被人改了,感到很受打击.<br><br>还有其他别的感受吗?&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/101550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-11-21 12:55 <a href="http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>函数参数的理想个数</title><link>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 03 Aug 2009 09:35:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/92059.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/92059.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/92059.html</trackback:ping><description><![CDATA[摘译自: <br><br>Clean Code<br>A Handbook of Agile<br>Software Craftsmanship<br>Robert C. Martin<br><br><br>Function Arguments<br><br>The ideal number of arguments for a function is<br>zero (niladic). Next comes one (monadic), followed<br>closely by two (dyadic). Three arguments (triadic)<br>should be avoided where possible. More than three<br>(polyadic) requires very special justification—and<br>then shouldn&#8217;t be used anyway.<br><br>函数参数<br><br>函数参数的理想个数是零个（零元）。<br>其次是一个（一元），<br>紧接下来是两个（二元）。<br>三个参数（三元）应尽可能地避免。<br>三个以上的参数（多元）需要非常特殊的理由<br>————否则无论如何都不应该。<br><br>（转载请注明来源于金庆的专栏）<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/92059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-08-03 17:35 <a href="http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN中邪恶的replace</title><link>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 18 Jun 2009 06:53:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/87977.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/87977.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/87977.html</trackback:ping><description><![CDATA[SVN中邪恶的replace<br><br>（转载请注明来源于金庆的专栏）<br><br>用TSVN客户端删除一个文件, 然后再新建一个同名文件, <br>可以看到该文件上的图标被打上了TSVN的小红叉.<br>然后Add, Commit, 就会出现一条replace记录.<br>replace的操作会有个提示, 就是Add(as replacement)...命令项与普通的Add不同．<br><br>意思应该是该文件被替换了.<br><br>邪恶之处是以前的更改日志显示不出来了.<br>用revision graph可以看到所有历史, 只是在replace处是断裂的.<br>也就是说替换的效果是重新开启一个文件的更改记录, 隐藏之前的记录.<br>我想不出什么情况下需要这种功能.<br><br>更邪恶的是, revert changes from this revision会失败(TSVN 1.4.3).<br>错误原因是该文件的上个版本不存在.<br>好像所有的Add操作都是无法revert, 应该算是个缺陷吧?<br><br>为了还原该替换，须删除该文件, 然后revert changes from this revision.<br><br>
<br> <img src ="http://www.cppblog.com/jinq0123/aggbug/87977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-06-18 14:53 <a href="http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试替身(Test Double)的定义</title><link>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 18 May 2009 10:52:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/83306.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/83306.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/83306.html</trackback:ping><description><![CDATA[摘自：http://blog.vsharing.com/wooley/A801453.html<br><br>
<p>&nbsp;&nbsp;<strong>测试替身</strong>(Test Double)<strong>的定义</strong>  </p>
<p>&nbsp;</p>
<table class="MsoNormalTable" style="border: medium none ; width: 100%; border-collapse: collapse;" width="100%" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="border: 1pt dotted lightgrey; padding: 0.35pt;">
            <p><strong>测试替身型别</strong><strong></strong></p>
            </td>
            <td style="border-style: dotted dotted dotted none; border-color: lightgrey lightgrey lightgrey -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0.35pt;">
            <p><strong>描述</strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Dummy</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>最简单、最原始的测试替身型别。Dummy 没有实作，最常用于需要参数值但不使用它的情况。Null 可视为是 Dummy，但真的 Dummy 是接口或基类的衍生，且完全不包含实作。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Stub</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Dummy 的上一级，Stub 是接口或基类的最低限度实作。会传回 Void 的方法通常完全不包含实作，而会传回值的方法通常会传回硬式编码的值。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Spy</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>测试 Spy 类似 Stub，但除了提供客户端可叫用成员的实例，Spy 还会记录叫用了哪些成员，好让单元测试验证所叫用的成员是否符合预期。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Fake</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Fake 包含更复杂的实作，通常涉及所继承型别之不同成员之间的互动。虽然不是完整的生产实作，但 Fake 与生产实作很相似，尽管它会采取一些快捷方式。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Mock</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Mock 是由 Mock 链接库动态建立 (其他通常是由测试开发人员使用程序代码来产生)。测试开发人员永远看不到实作接口或基类的实际程序代码，但是可以设定 Mock 以提供传回值、预期要叫用的特定成员...等等。视其中的设定而定，Mock 的行为可能会像 Dummy、Stub 或 Spy。</p>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;
<br><br><img src ="http://www.cppblog.com/jinq0123/aggbug/83306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-05-18 18:52 <a href="http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决TSVN的diff显示中文件不全的问题</title><link>http://www.cppblog.com/jinq0123/archive/2009/02/14/73780.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 14 Feb 2009 05:30:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/02/14/73780.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/73780.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/02/14/73780.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/73780.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/73780.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: TortoiseSVN的diff显示中文有些问题, 多数不能完整显示出来. 好像是整个TortoiseSVN对中文字符都有问题, 如blame会崩溃,但是选中"Use test viewer..."用Notepad显示就会正常.&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/02/14/73780.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/73780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-02-14 13:30 <a href="http://www.cppblog.com/jinq0123/archive/2009/02/14/73780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>