<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>“技术奇异点” 的评论</title>
	<atom:link href="http://techsingular.net/?feed=comments-rss2" rel="self" type="application/rss+xml" />
	<link>http://techsingular.net</link>
	<description>You are what you program</description>
	<lastBuildDate>Tue, 24 Aug 2010 03:38:10 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>cppof286 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-974</link>
		<dc:creator>cppof286</dc:creator>
		<pubDate>Tue, 24 Aug 2010 03:38:10 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-974</guid>
		<description>补充一下：

a) 我所谓的“被迫调试一个自己从来没见过的问题”，一般指调试完全不是自己写的代码。程序员可能会对大体概念上有些了解，而对很多细节（数据结构、算法，甚至代码的框架选择）一无所知。这种情况最典型地出现在接手别人的工作时。在一些极端情况下（取决于原先的代码质量），这种情况甚至可能伴随整个工作过程。

b) 其实我和前面几位的观点并无实质差别。Log和debugger作为工具而言并无高下之别，只看是否适用，但我更希望明确地表述“究竟什么是合适做选择的时候”，而不是泛泛地讲“合适的时候选择合适的工具”。</description>
		<content:encoded><![CDATA[<p>补充一下：</p>
<p>a) 我所谓的“被迫调试一个自己从来没见过的问题”，一般指调试完全不是自己写的代码。程序员可能会对大体概念上有些了解，而对很多细节（数据结构、算法，甚至代码的框架选择）一无所知。这种情况最典型地出现在接手别人的工作时。在一些极端情况下（取决于原先的代码质量），这种情况甚至可能伴随整个工作过程。</p>
<p>b) 其实我和前面几位的观点并无实质差别。Log和debugger作为工具而言并无高下之别，只看是否适用，但我更希望明确地表述“究竟什么是合适做选择的时候”，而不是泛泛地讲“合适的时候选择合适的工具”。</p>
]]></content:encoded>
	</item>
	<item>
		<title>cppof286 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-973</link>
		<dc:creator>cppof286</dc:creator>
		<pubDate>Tue, 24 Aug 2010 03:27:20 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-973</guid>
		<description>其实我所强调的不是两个都能解决问题，我强调的是两种手段其实是适合不同的场景。

后来我私下和东哥在MSN上重新聊了一次，表达上有些改变。我比较倾向于这样组织我的看法：log和debugger虽然理论上范围没有明确的界限，但各自有各自更适合的领域。我喜欢把一个调试的过程主要分为两个解决：

a) 从完全不知道目标（只看到程序执行不正常），到大约知道目标会在哪个模块（比如一个DCOM控件失败，我是该怀疑COM runtime，还是主调程序，还是被调程序）；
b) 从大约知道在哪个模块到确定到问题的根源。

前者是宏观的定位，后者则是微观的定点打击。我的观点是log在我的个人实践中更适合在场景a)帮助程序员缩小怀疑范围——因为有时候一个bug涉及多个模块甚至多个产品，没法一个个调试；而debugger则适合在场景b)帮助找到最终根源——因为到这个阶段的时候程序员已经能把怀疑范围固定到一个进程里了。所以我不是很喜欢把这两者拿来对比。

我们很多时候没有注意这两者的分别，是因为调试过程中还有程序员知识的存在。很多程序员不愿意在开发阶段考虑log，很大程度上是因为他们自己可以通过自己对代码的了解弥补工具的不足，所以我们经常能看到一个程序员拿log或者debugger包打天下的情况。

但是，当程序员被迫去调试一个自己从来没有见过的问题时，这两个工具的差异就体现出来了：log的粒度更粗（所以程序员才会去急急忙忙地加printf，为的就是显示微观信息），但是它的表述更具描述性；debugger粒度细，可以精确到每个变量，却无法在宏观上反映模块间的执行流程。这种情况下如果非要让两者互相替代，只能是吃力不讨好。


至于是否干扰执行呢，确实是要看具体的bug是不是会被影响而定的。我是针对东哥前面说的UI而言的。就我的经验来说，UI程序是非常典型的debugger严重干扰执行流进而干扰问题分析的场合。我曾经处理过一个Windows环境下由于钩子函数性能问题导致在切换窗口中消息派发错误的问题。那个例子是非常典型的无法使用调试器的场景，因为任何情况下执行流程被断下都会导致消息传送错误，结果就是一旦上调试器几乎100%无法重现。</description>
		<content:encoded><![CDATA[<p>其实我所强调的不是两个都能解决问题，我强调的是两种手段其实是适合不同的场景。</p>
<p>后来我私下和东哥在MSN上重新聊了一次，表达上有些改变。我比较倾向于这样组织我的看法：log和debugger虽然理论上范围没有明确的界限，但各自有各自更适合的领域。我喜欢把一个调试的过程主要分为两个解决：</p>
<p>a) 从完全不知道目标（只看到程序执行不正常），到大约知道目标会在哪个模块（比如一个DCOM控件失败，我是该怀疑COM runtime，还是主调程序，还是被调程序）；<br />
b) 从大约知道在哪个模块到确定到问题的根源。</p>
<p>前者是宏观的定位，后者则是微观的定点打击。我的观点是log在我的个人实践中更适合在场景a)帮助程序员缩小怀疑范围——因为有时候一个bug涉及多个模块甚至多个产品，没法一个个调试；而debugger则适合在场景b)帮助找到最终根源——因为到这个阶段的时候程序员已经能把怀疑范围固定到一个进程里了。所以我不是很喜欢把这两者拿来对比。</p>
<p>我们很多时候没有注意这两者的分别，是因为调试过程中还有程序员知识的存在。很多程序员不愿意在开发阶段考虑log，很大程度上是因为他们自己可以通过自己对代码的了解弥补工具的不足，所以我们经常能看到一个程序员拿log或者debugger包打天下的情况。</p>
<p>但是，当程序员被迫去调试一个自己从来没有见过的问题时，这两个工具的差异就体现出来了：log的粒度更粗（所以程序员才会去急急忙忙地加printf，为的就是显示微观信息），但是它的表述更具描述性；debugger粒度细，可以精确到每个变量，却无法在宏观上反映模块间的执行流程。这种情况下如果非要让两者互相替代，只能是吃力不讨好。</p>
<p>至于是否干扰执行呢，确实是要看具体的bug是不是会被影响而定的。我是针对东哥前面说的UI而言的。就我的经验来说，UI程序是非常典型的debugger严重干扰执行流进而干扰问题分析的场合。我曾经处理过一个Windows环境下由于钩子函数性能问题导致在切换窗口中消息派发错误的问题。那个例子是非常典型的无法使用调试器的场景，因为任何情况下执行流程被断下都会导致消息传送错误，结果就是一旦上调试器几乎100%无法重现。</p>
]]></content:encoded>
	</item>
	<item>
		<title>chenxiaoyan 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-972</link>
		<dc:creator>chenxiaoyan</dc:creator>
		<pubDate>Tue, 24 Aug 2010 01:00:23 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-972</guid>
		<description>说自己解决过的一个问题：
从程序逻辑看这个问题非常怪异，根本无法重现，只能首先分析log，分析后猜测是由于线程调度问题某个对象持有了另一个无效对象的引用，（不是死锁问题），然后在debug模式下人为挂起/继续线程的执行，一共有三个线程，但每个线程的执行路径都很长，最后总结出了18个步骤，在debug模式下按照这18个步骤来安排这三个线程的调度顺序就能100%地重现问题</description>
		<content:encoded><![CDATA[<p>说自己解决过的一个问题：<br />
从程序逻辑看这个问题非常怪异，根本无法重现，只能首先分析log，分析后猜测是由于线程调度问题某个对象持有了另一个无效对象的引用，（不是死锁问题），然后在debug模式下人为挂起/继续线程的执行，一共有三个线程，但每个线程的执行路径都很长，最后总结出了18个步骤，在debug模式下按照这18个步骤来安排这三个线程的调度顺序就能100%地重现问题</p>
]]></content:encoded>
	</item>
	<item>
		<title>Singularity 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-968</link>
		<dc:creator>Singularity</dc:creator>
		<pubDate>Sun, 22 Aug 2010 14:21:32 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-968</guid>
		<description>其实我的意思就是哪个合适用哪个。只是我以前认为适合debugger的问题域太小，最近才发现其实适合debugger的问题域比我想像的要大很多。如果只是我的无知我也不想写这篇blog，而是我发现很多工作很久的同事也并不知道这些。</description>
		<content:encoded><![CDATA[<p>其实我的意思就是哪个合适用哪个。只是我以前认为适合debugger的问题域太小，最近才发现其实适合debugger的问题域比我想像的要大很多。如果只是我的无知我也不想写这篇blog，而是我发现很多工作很久的同事也并不知道这些。</p>
]]></content:encoded>
	</item>
	<item>
		<title>doing 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-967</link>
		<dc:creator>doing</dc:creator>
		<pubDate>Sun, 22 Aug 2010 11:53:52 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-967</guid>
		<description>debugger是debugger，log是log。

这两个都可以解决问题，但是在不同的场合有不同的优势，本来就是哪个合适用哪个，何必拘泥？

至于cppof286提到的b、c两点，我个人是非常赞同的。

至于a有保留意见，是否干扰执行并不重要，如果可以诊断出问题，是否干扰了执行无所谓。如果干扰导致不能诊断问题，那自然就不用这个方法好了，算不上什么禁招。</description>
		<content:encoded><![CDATA[<p>debugger是debugger，log是log。</p>
<p>这两个都可以解决问题，但是在不同的场合有不同的优势，本来就是哪个合适用哪个，何必拘泥？</p>
<p>至于cppof286提到的b、c两点，我个人是非常赞同的。</p>
<p>至于a有保留意见，是否干扰执行并不重要，如果可以诊断出问题，是否干扰了执行无所谓。如果干扰导致不能诊断问题，那自然就不用这个方法好了，算不上什么禁招。</p>
]]></content:encoded>
	</item>
	<item>
		<title>luke 关于 Git、P4merge 和 OS X 的评论</title>
		<link>http://techsingular.net/?p=922&#038;cpage=1#comment-963</link>
		<dc:creator>luke</dc:creator>
		<pubDate>Sat, 21 Aug 2010 02:00:02 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=922#comment-963</guid>
		<description>git config  diff.tool p4merge
git config  &#039;difftool.p4merge.cmd /Applications/p4merge.app/Contents/MacOS/p4merge \&quot;\$LOCAL\&quot; \&quot;\$REMOTE\&quot;&#039;

这么写我这里不行啊， 调起来了 但是是自带的filemerge 不是p4merge 怎么回事啊？</description>
		<content:encoded><![CDATA[<p>git config  diff.tool p4merge<br />
git config  &#8216;difftool.p4merge.cmd /Applications/p4merge.app/Contents/MacOS/p4merge \&#8221;\$LOCAL\&#8221; \&#8221;\$REMOTE\&#8221;&#8216;</p>
<p>这么写我这里不行啊， 调起来了 但是是自带的filemerge 不是p4merge 怎么回事啊？</p>
]]></content:encoded>
	</item>
	<item>
		<title>cppof286 关于 接受调试器 的评论</title>
		<link>http://techsingular.net/?p=1062&#038;cpage=1#comment-960</link>
		<dc:creator>cppof286</dc:creator>
		<pubDate>Thu, 19 Aug 2010 01:16:09 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=1062#comment-960</guid>
		<description>几条意见：

a) UI调试适合使用debugger：在Windows下我旗帜鲜明地反对这一点。现今流行的Windows UI framework对多线程和事件等待的依赖过于强烈，任何随意设置断点的行为都可能影响程序的执行过程，这种条件下设置断点是典型的禁招。

b) 至于远程调试帮助解决UI调试问题——这是另一个问题 。很早以前WinDBG就已经发展出了-remote和-premote两种远程调试法。

c) 补充一个个人观点：就我目前所经历的所有情况看，认为log没有debugger好用人都往往自己假设了一个基本前提，就是代码原来没有信息输出，出错了才开始急急忙忙地加printf调试。在我看来这个不叫log，只能叫临时抱佛脚。——Debugger比这种“log”好用是必然的，因为这种情况下程序员的任务是从无到有地构造探查范围，Debugger的call stack和断点比printf好用得多。

合理设计的log应该是一开始就内嵌在系统里的，它的所有开销必须是程序设计时就得考虑进去，什么信息可以输出，什么信息不能输出都必须是设计阶段就定好的。除非真的有非常特殊的理由，否则任何试图在设计阶段忽略log的行为我认为都是不合格的体现。

重复：printf != log</description>
		<content:encoded><![CDATA[<p>几条意见：</p>
<p>a) UI调试适合使用debugger：在Windows下我旗帜鲜明地反对这一点。现今流行的Windows UI framework对多线程和事件等待的依赖过于强烈，任何随意设置断点的行为都可能影响程序的执行过程，这种条件下设置断点是典型的禁招。</p>
<p>b) 至于远程调试帮助解决UI调试问题——这是另一个问题 。很早以前WinDBG就已经发展出了-remote和-premote两种远程调试法。</p>
<p>c) 补充一个个人观点：就我目前所经历的所有情况看，认为log没有debugger好用人都往往自己假设了一个基本前提，就是代码原来没有信息输出，出错了才开始急急忙忙地加printf调试。在我看来这个不叫log，只能叫临时抱佛脚。——Debugger比这种“log”好用是必然的，因为这种情况下程序员的任务是从无到有地构造探查范围，Debugger的call stack和断点比printf好用得多。</p>
<p>合理设计的log应该是一开始就内嵌在系统里的，它的所有开销必须是程序设计时就得考虑进去，什么信息可以输出，什么信息不能输出都必须是设计阶段就定好的。除非真的有非常特殊的理由，否则任何试图在设计阶段忽略log的行为我认为都是不合格的体现。</p>
<p>重复：printf != log</p>
]]></content:encoded>
	</item>
	<item>
		<title>无形 关于 技术的暴力美学 的评论</title>
		<link>http://techsingular.net/?p=823&#038;cpage=1#comment-923</link>
		<dc:creator>无形</dc:creator>
		<pubDate>Tue, 27 Jul 2010 05:43:17 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=823#comment-923</guid>
		<description>Singularity说的甚是，西方用sr-71的逻辑推出米格15所以困扰很多年。</description>
		<content:encoded><![CDATA[<p>Singularity说的甚是，西方用sr-71的逻辑推出米格15所以困扰很多年。</p>
]]></content:encoded>
	</item>
	<item>
		<title>yucca 关于 Open Source 的界限 的评论</title>
		<link>http://techsingular.net/?p=804&#038;cpage=1#comment-922</link>
		<dc:creator>yucca</dc:creator>
		<pubDate>Mon, 26 Jul 2010 12:43:10 +0000</pubDate>
		<guid isPermaLink="false">http://sipoint.wordpress.com/?p=804#comment-922</guid>
		<description>那linux发行版应该死光光，而且开源的软件应该都没有GUI，因为为软件开发GUI的项目都活不了</description>
		<content:encoded><![CDATA[<p>那linux发行版应该死光光，而且开源的软件应该都没有GUI，因为为软件开发GUI的项目都活不了</p>
]]></content:encoded>
	</item>
	<item>
		<title>Singularity 关于 拿到了 CS5 的评论</title>
		<link>http://techsingular.net/?p=990&#038;cpage=1#comment-910</link>
		<dc:creator>Singularity</dc:creator>
		<pubDate>Mon, 19 Jul 2010 20:49:10 +0000</pubDate>
		<guid isPermaLink="false">http://techsingular.net/?p=990#comment-910</guid>
		<description>哈哈。这两天刚换了车，比较忙。其实每天还上去看看，发现最新的还是Oliver兄关于Palm的，所以也就暂时没发帖。回头一定再讨论。</description>
		<content:encoded><![CDATA[<p>哈哈。这两天刚换了车，比较忙。其实每天还上去看看，发现最新的还是Oliver兄关于Palm的，所以也就暂时没发帖。回头一定再讨论。</p>
]]></content:encoded>
	</item>
</channel>
</rss>
