提问的智慧

艾瑞克.史蒂文.雷蒙德(Eric Steven Raymond)

瑞克.莫恩(Rick Moen)

版权©2001, 2006 Eric S. Raymond, Rick Moen

 

修订历史
修订版 3.9 2013年4月23日 esr
修正链接
修订版 3.8 2012年6月19日 esr
修正链接
修订版 3.7 2010年12月6日 esr
对于英语为第二语言人士的有益建议
修订版 3.7 2010年11月2日 esr
几种翻译不见了
修订版 3.6 2008年3月19日 esr
小更新及新链接
修订版 3.5 2008年1月2日 esr
勘误及一些翻译链接
修订版 3.4 2007年3月24日 esr
新章节:“关于代码的问题”
修订版 3.3 2006年9月29日 esr
增加凯.尼格曼(Kai Niggemann)的一个好建议
修订版 3.2 2006年1月10日 esr
加入瑞克.莫恩(Rick Moen)编写的内容
修订版 3.1 2004年10月28日 esr
文档“谷歌是你的朋友!”
修订版 3.0 2004年2月2日 esr
主要新增在网页论坛应有的礼节

 


原文How To Ask Questions The Smart Way

翻译:王刚 <yafrank at 126 dot com>    
时间:2013年10月26日

内容

译文
弃权申明
引言
提问前
提问时
仔细挑选论坛
面向新手的论坛和互联网中继聊天(IRC)通常响应最快
第二步,使用项目的邮件列表
使用有意义且明确的主题
使问题容易回复
用清晰、语法、拼写正确的语句书写
使用易于读取且标准的文件格式发送问题
描述问题应准确且有内容
量不在多,精炼则灵
别急于宣称找到臭虫
低声下气代替不了做自己的家庭作业
描述问题症状而不是猜测
按时间先后罗列问题症状
描述目标而不是过程
别要求私下回复电邮
提问应明确
关于代码的问题
别张贴家庭作业式问题
删除无意义的要求
不要把问题标记为“紧急”, 即使对你而言的确如此
礼貌总是有益的
问题解决后追加一条简要说明
如何解读回答
“读读该死的手册”(RTFM)和“搜搜该死的网络”(STFW):如何明白你已完全搞砸
如果还不明白……
对待无礼
别象失败者那样反应
提问禁忌
好问题与坏问题
如果得不到回答
如何更好地回答
相关资源
鸣谢

弃权申明

 

 

 

许多项目的网站在如何取得帮助的部分链接了本文,这没有关系,也正是我们想要的。但如果你是该项目生成此链接的网管,请在链接附近显著位置注明:我们不提供该项目的服务支持!

我们已经领教了没有此说明带来的痛苦,我们将不停地被一些白痴纠缠,他们认为既然我们发布了本文,那么我们就有责任解决世上所有的技术问题。

如果你是因为需要帮助正在阅读本文,然后就带着可以直接从作者那取得帮助的印象离开,那么 就不幸成了我们所说的白痴之一。 别向 我们 提问,我们不会理睬的。 我们只是在这教你如何从那些真正懂得你软硬件问题的人那里取得帮助,但 99.9% 的时间我们不会是那些人。除非你非常地 确定 本文的作者是你遇到问题方面的专家,请不要打搅,这样大家都更开心一点。

 

引言

 

 

 

黑客 的世界里,你所提技术问题的解答很大程度上取决于你提问的方式与解决此问题的难度,本文将教你如何提问才更有可能得到满意的答复。

开源程序的应用已经很广,你通常可以从其他更有经验的用户而不是黑客那里得到解答。这是好事,他们一般对新手常有的毛病更容忍一点。然尔,使用我们推荐的方法,象对待黑客那样对待这些有经验的用户,通常能最有效地得到问题的解答。

第一件需要明白的事是黑客喜欢难题和激发思考的好问题。假如不是这样,我们也不会写本文了。如果你能提出一个有趣的问题让我们咀嚼玩味,我们会感激你。好问题是种激励与礼物,帮助我们发展认知,揭示没有注意或想到的问题。在黑客中,“好问题!” 是非常热烈而真挚的赞许。

此外,黑客还有遇到简单问题就表现出敌视或傲慢的名声。有时,我们看起来还对新手和愚蠢的家伙有条件反射式的无礼,但事情并不真是这样。

我们只是毫无歉意地敌视那些提问前不愿思考、不做自己家庭作业的人。这种人就象时间无底洞──他们只知道索取,不愿意付出,他们浪费了时间,这些时间本可用于其它更有趣的问题或更值得回答的人。我们将这种人叫做 “失败者(loser)” (由于历史原因,我们有时将“loser”拼写为“lusers” 。)

我们意识到许多人只是想使用我们写的软件,他们对学习技术细节没有兴趣。对大多数人而言,计算机只是种工具,是种达到目的的手段而已。他们有自己的生活并且有更要紧的事要做,我们承认这点,也从不指望每个人都对这些让我们着迷的技术问题感兴趣。不过,我们回答问题的风格是为了适应那些真正对此有兴趣并愿意主动参与解决问题的人,这一点不会变,也不该变。如果连这都变了,我们就会在自己能做得最好的事情上不再那么犀利。

我们(大多数)是自愿者, 从自己繁忙的生活中抽时间来回答问题,有时会力不从心。因此,我们会毫不留情地滤除问题,特别是那些看起来象是失败者提的,以便更有效地把回答问题的时间留给那些胜利者。

如果你认为这种态度令人反感、以施惠者自居或傲慢自大,请检查你的假设,我们并未要求你屈服──事实上,假如你做了该做的努力,我们中的大多数将非常乐意平等地与你交流,并欢迎你接纳我们的文化。试图去帮助那些不愿自救的人对我们简直没有效率。不懂没有关系,但愚蠢地做事不行。

所以,你不必在技术上很在行才能吸引我们的注意,但你 必须 表现出能引导你在行的姿态──机 敏、有想法、善于观察、乐于主动参与问题的解决。如果你做不到这些使你与众不同的事情,我们建议你付钱跟别人签商业服务合同,而不是要求黑客无偿帮助。

如果你决定向我们求助,你不会想成为一名失败者,你也不想被看成一个失败者。得到快速有效回答的最好方法是使提问者看起来象个聪明、自信和有想法的人,并且暗示只是碰巧在某一特别问题上需要帮助。

(欢迎对本文指正,可以将建议发至 [email protected][email protected]
请注意,本文不想成为一般性的 网络礼仪 指南,我一般会拒绝那些与引出技术论坛中有用的回答不特别相关的建议。)

 

提问

 

 

 

在通过电邮、新闻组或论坛提技术问题以前,做以下事情:

  1. 尝试在你准备提问论坛的历史文档中搜索答案

  2. 尝试搜索互联网以找到答案

  3. 尝试阅读手册以找到答案

  4. 尝试阅读“常见问题文档”(FAQ)以找到答案

  5. 尝试自己检查或试验以找到答案

  6. 尝试请教懂行的朋友以找到答案

  7. 如果你是程序员,尝试阅读源代码以找到答案

提问时,请先表明你已做了上述事情,这将有助于建立你不是寄生虫与浪费别人时间的印象。最好再表述你从中 学到的东西 ,我们喜欢回答那些表现出能从答案中学习的人。

运用某些策略,比如用谷歌(Google)搜索你遇到的各种错误提示(既搜索 谷歌论坛,也搜索网页), 这样很可能直接就找到了解决问题的文档或邮件列表线索。 即使没有结果,在邮件列表或新闻组寻求帮助时提一句“我在谷歌中搜过下列句子但没有找到什么有用的东西” 也是件好事,至少它表明了搜索引擎不能提供哪些帮助。将搜索关键词与你的问题及可能的解决方案联系起来,还有助于引导其他有类似问题的人。

别着急,不要指望几秒钟的谷歌搜索就能解决一个复杂的问题。读一下常见问题文档。在向专家提问之前,先向后靠靠放松一下,再思考一下问题。相信我们,他们能从你的提问看出你做了多少阅读与思考,如果你是有备而来,将更有可能得到解答。不要将所有问题一股脑抛出,只因你的第一次搜索没有结果(或者结果太多)。

认真地思考,准备好你的问题。轻率的提问只能得到轻率的回答,或者压根没有。在提问时,你越是表现出在此前做过思考与努力去解决自己的问题,你越有可能得到真正的帮助。

注意别提错问题。如果提问基于错误的假设,某黑客多半会一边想 “愚蠢的问题……”,一边按将错就错的答案回复你,并且希望这种只是得到你自己“问的问题”而非真正所需的解答,给你一个教训。

永远不要假设你 有资格 得到解答。你没有这种资格,毕竟你没有为此服务付费。如果你能够提出有内容、有趣和激励思考的问题──那种毫无疑问能够向社区贡献经验,而不仅仅是消极地要求从别人那获取知识的问题,你将“挣到”答案。

另一方面,表明你有能力也乐意参与问题的解决是个很好的开端。“有没有人能指个方向?”,我这还差点什么?”,“我应该查哪个网站?”,通常要比 “请给出我可以用的完整步骤”更容易得到回复,因为你表明了只要有人能指个方向,你就很乐意完成剩下的过程。

 

提问时

 

 

 

仔细挑选论坛

 

 

 

要对在哪提问留心,如果你做了下述事情,多半会被一笔勾销或被看成“失败者”:

  • 张贴与论坛主题无关的问题

  • 在面向高级技术问题的论坛上张贴肤浅的问题,或者反之。

  • 在太多不同的新闻组同时张贴

  • 给既非熟人也没有义务解决你问题的人发送你私人的电邮

为保护通信的渠道不被无关的东西淹没,黑客会除掉那些没有找对地方的问题,你不会想让这种事落到自己头上的。

因此,第一步是找对论坛。谷歌和其它搜索引擎还是你的朋友,可以用它们搜索你遇到困难的软硬件问题最相关的项目网站。那里通常都有项目的常见问题(FAQ)、邮件列表及文档的链接。如果你的努力(包括 阅读 FAQ)都没有结果,这些邮件列表就是最后能取得帮助的地方。项目的网站也许还有报告臭虫的流程或链接,如果是这样,去看看。

向陌生的人或论坛发送邮件极有可能是在冒险。譬如,不要假设一个内容丰富的网页的作者想充当你的免费顾问,不要对你的问题是否会受到欢迎做太乐观的估计──如果你不确定,向别处发或者压根别发。

在选择论坛、新闻组或邮件列表时,别太相信名字,先看看 FAQ 或者许可书以明确你的问题是否切题。发贴前先翻翻已有的帖子,这样可以让你感受一下那里行事的方式。事实上,张贴前在新闻组或邮件列表的历史文档中搜索与你问题相关的关键词是个极好的主意,也许就找到答案了。即使没有,也能帮助你归纳出更好的问题。

别象机关枪似的一次性“扫射”所有的帮助渠道,这就象大喊大叫一样会令人不快,温柔地一个一个来。

弄懂主题!最典型的错误之一是在某种致立于跨平台可移植的语言、库或工具的论坛中提关于 Unix 或 Windows 操作系统程序接口的问题。如果你不明白为什么这是大错,最好在搞清楚概念前什么也别问。

一般来说,在仔细挑选的公共论坛中提问比在私有论坛中提同样的问题更容易得到有用的回答。有几个道理支持这点,一是看潜在的回复者有多少,二是看论坛的参与者有多少,黑客更愿回答能启发多数人的问题。

可以理解,老练的黑客和一些流行软件的作者正在承受过多的不当消息。就象那根最后压垮骆驼背的稻草一样,你的加入也有可能使情况走向极端──已经好几次了,一些流行软件的作者退出了对自己软件的支持,因为伴随而来的涌入其私人邮箱的垃圾邮件变得无法忍受。

 

面向新手的论坛和互联网中继聊天(IRC)通常响应最快

 

 

 

本地的用户组织或者你所用的 Linux 发行版也许正在宣传新手取得帮助的论坛或 IRC 通道(在一些非英语国家,新手论坛很可能还是邮件列表),这些地方是开始提问的好去处,特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。经过宣传的 IRC 通道是公开邀请提问的地方,通常可以得到实时的回复。

事实上,如果出问题的程序来自某发行版(这很常见),最好先去该发行版的论坛或邮件列表中提问,再到程序本身的项目论坛或邮件列表,(否则)该项目的黑客可能仅仅回复“ 我们的 代码”。

在任何论坛发贴以前,先看看有没有搜索功能。如果有,就试着用问题的几个关键词搜索一下,也许就有帮助。如果在此之前你已做过全面的网页搜索(你应该这样去做),还是再搜索一下论坛,搜索引擎有可能没来得及索引此论坛的全部内容。

通过论坛或 IRC 通道提供项目的用户支持有增长的趋势,电子邮件交流则更多地为项目开发者保留。所以先在论坛或 IRC 中寻求与该项目相关的帮助。

 

第二步,使用项目的邮件列表

 

 

 

当某个项目存在开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。查一查项目的文档和主页,找到项目的邮件列表并使用它。采用这种办法有几个很好的理由:

  • 向个别开发者提的问题(如果)足够好,也将对整个项目组有益。相反,如果你认为自己的问题对整个项目组来说太愚蠢,这也不能成为骚扰个别开发者的理由。

  • 向列表提问可以分散开发者的负担,个别开发者(尤其是项目领导)也许太忙以至于没法回答你的问题。

  • 大多数邮件列表都要存档,那些存档将被搜索引擎索引,如果你向列表提问并得到解答,将来其它人可以通过网页搜索找到你的问题和答案,也就不用再次发问了。

  • 如果某些问题经常被问到,开发者可以利用此信息改进文档或软件本身,以使其更清楚。如果只是私下提问,就没有人能看到最常见问题的完整场景。

如果一个项目既有 “用户” 也有“开发者”(或 “黑客”)邮件列表或论坛,而你又不摆弄那些代码,向“用户”列表或论坛提问。不要假设自己会在开发者列表中受到欢迎,那些人多半会遭受你的噪音干扰。

然尔,如果你 确信 你的问题不一般,而且在“用户” 列表或论坛中几天都没有回复,可以试试“开发者”列表或论坛。建议你在张贴前最好先暗暗地观察几天,至少看看最近几天保存的帖子,以了解那的行事方式(事实上这是参与任何私有或半私有列表的好主意)

如果你找不到一个项目的邮件列表,而只能查到项目维护者的地址,只管向其发信。即便在这种情况下,也别假设(项目)邮件列表不存在。在你的电子邮件中陈述你已经试过但没有找到合适的邮件列表,也提及你不反对将自己的邮件转发给他人(许多人认为,即使没什么秘密,私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人,你给了相应人员处置你邮件的选择)。

 

使用有意义且明确的主题

 

 

 

在邮件列表、新闻组或论坛中,主题是你在五十个或更少的字以内吸引有资格专家注意的黄金机会,不要用诸如 “请帮我” (更别提大写的 “请帮我!!!!”,这种主题的消息会被条件反射式地删掉)之类的唠叨浪费机会。不要用你痛苦的深度来打动我们,相反,要在这点空间中使用超级简明扼要的问题描述。

使用主题的好惯例是“对象──偏差”(式的描述),许多技术支持组织就是这样做的。在“对象”部分指明是哪一个或哪一组东西有问题,在“偏差”部分则描述与期望的行为不一致的地方。

愚蠢:

救命啊!我的笔记本视频工作不正常!

明智:

X.org 6.8.1 扭曲鼠标光标,MV1005 型号的某显卡芯片组

更明智:

使用 MV1005 型号的某显卡芯片组在 X.org 6.8.1 的鼠标光标被扭曲

编写 “对象──偏差”式描述的过程有助于你组织对问题的细致思考。是什么被影响了?仅仅是鼠标光标或者还有其它图形?只在 X.org 中出现?或只是在其 6.8.1 版中?是针对某显卡芯片组?或者只是其中的 MV1005 型号?一个黑客只需描一眼就能够立即明白什么是你遇到的问题,什么是你自己的问题。

更一般地,想象一下在一个只显示主题的文档索引中查找。让你的主题更好地反映问题,可以使下一个搜索类似问题的人能够在文档中直接就找到答案的线索,而不用再次发贴提问。

如果你想在回复中提问,确保改变主题以表明你是在问一个问题,一个主题象 “Re: 测试” 或者 “Re: 新臭虫”的消息不太可能引起足够的注意。同时,将回复中与新主题不甚相关的引用内容尽量删除。

对于列表消息,不要直接点击回复(按钮)来开始一个全新的线索,这将限制你的观众。有些邮件阅读程序,比如 mutt,允许用户按线索排序并通过折叠线索来隐藏消息,这样做的人永远看不到你发的消息。

仅仅改变主题还不够。mutt 和其它一些邮件阅读程序还要检查邮件头主题以外的其它信息,以便为其指定线索,所以宁可发一个全新的邮件。

在论坛,因为消息与特定的线索紧密结合,并且通常在线索之外不可见,好的提问方式略有不同,通过回复提问并不要紧。不是所有论坛都允许在回复中出现分离的主题,而且这样做了基本上没有人会去看。不过,通过回复提问本身就是令人怀疑的做法,因为它们只会被正在查看该线索的人读到。所以,除非你 只想 在该线索当前活跃的人群中提问,还是另起炉灶比较好。

 

使问题容易回复

 

 

 

以“请向……回复”来结束问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦,我们也觉得花几秒钟考虑你的问题更麻烦。如果你的邮件客户端程序不支持这样做,换个好点的;如果是操作系统不支持所有这种邮件客户端程序,也换个好点的。

在论坛,要求通过电子邮件回复是完全无礼的,除非你确信回复的信息也许是敏感的(而且有人会为了某些未知的原因,只让你而不是整个论坛知道答案)。如果你只是想在有人回复线索时得到电子邮件提醒,可以要求论坛发送。几乎所有论坛都支持诸如“留意本线索”、“有回复发送邮件”等功能。

 

用清晰、语法、拼写正确的语句书写

 

 

 

经验告诉我们,粗心与草率的作者通常也粗心与草率地思考和编程(我敢打赌)。为这些粗心与草率的思考者回答问题没有什么好处,我们宁可将时间花在其它地方。

清楚、良好地表达你的问题非常重要。如果你觉得这样做麻烦,我们也觉得注意(你的问题)麻烦。花点额外的精力斟酌一下字句,用不着太僵硬与正式──事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它 必须 很准确,而且有迹象表明你是在思考和关注问题。

正确地拼写、使用标点和大小写,不要将“its”混淆为“it's”,“loose”搞成“lose”或者将“discrete”弄成 “discreet”。不要全部用大写,这会被视为无礼的大声嚷嚷 (全部小写也好不到哪去,因为不易阅读。Alan Cox [注:著名黑客,Linux 内核的重要参与者] 也许可以这样做,但你不行。)

一般而言,如果你写得象个半文盲似的傻子,多半得不到理睬。也不要使用即时通讯中的简写,如将“you”简化为“u”会使你看起来象一个为了节约二次击键的半文盲式的傻子。更糟的是,如果象个小孩似地鬼画桃符那绝对是在找死,可以肯定没人会理你(或者最多是给你一大堆指责与挖苦)。

如果在非母语论坛提问,你的拼写与语法错误会得到有限的宽容,但懒惰完全不会被容忍(是的,我们通常看得出其中的差别)。同时,除非你知道回复者使用的语言,请使用英语书写。繁忙的黑客一般会直接删除用他们看不懂语言写的消息。在互联网上英语是工作语言,用英语书写可以将你的问题不被阅读就被直接删除的可能性降到最低。

 

如果你用英语书写但它是你的第二语言,最好提醒潜在的回复者语言上可能的困难以便绕过这个问题,比如:

  • 英语不是我的母语,请谅解拼写错误。

  • 如果您使用某某语言,请电邮/私聊我,也许我需要您的协助翻译我的问题。

  • 对于这个技术术语本身我很熟悉,但对于它的一些俚语或习惯表达方式就不太明白了。

  • 我已经同时用某某语及英语提问,如果您使用两者之一回复,我很乐意翻译。

 

使用易于读取且标准的文件格式发送问题

 

 

 

如果你人为地将问题搞得难以阅读,它多半会被忽略,人们更愿读易懂的问题,所以:

  • 使用纯文本而不是 HTML(超文本标注语言)( 关闭HTML 并不难)

  • 使用 MIME(多用途互联网邮件扩展)附件通常没有问题,前提是真正有内容(譬如附带的源文件或补丁),而不仅仅是邮件客户端程序生成的模板(譬如只是消息内容的拷贝)。

  • 不要发送整段只是单行句子但多次折回的邮件(这使得回复部分内容非常困难)。设想你的读者是在80个字符宽的文本终端阅读邮件,设置你的行折回点小于 80 列。

  • 但是,也 不要 用任何固定列折回数据(譬如日志文件拷贝或会话记录)。数据应该原样包含,使回复者确信他们看到的是与你看到的一样的东西。

  • 在英语论坛中,不要使用'Quoted-Printable' MIME 编码发送消息。这种编码对于张贴非 ASCII 语言可能是必须的,但很多邮件程序并不支持。当它们分断时,那些文本中四处散布的 “=20”符号既难看也分散注意力,甚至有可能破坏内容的语意。

  • 永远不要 指望黑客们阅读使用封闭的专用格式编写的文档,诸如微软公司的 Word 或 Excel 文件等。大多数黑客对此的反应就象有人将还在冒热气的猪粪倒在你门口时你的反应一样。即使他们能够处理,也很厌恶这么做。

  • 如果你从使用视窗的电脑发送电子邮件,关闭问题颇多的微软“聪明引用”功能(在“工具” -> “自动纠正选项”的“输入时自动格式化”下去掉聪明引用的选框),以免在你的邮件中到处散布垃圾字符。

  • 在论坛,勿滥用“表情符号”和“HTML”功能(当它们提供时)。一两个表情符号通常没有问题,但花哨的彩色文本倾向于使人认为你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来象个傻笑的小姑娘。这通常不是个好主意,除非你只是对性而不是有用的回复更有兴趣。

如果你使用图形用户界面的邮件客户端程序(如网景公司的 Messenger、微软公司的 Outlook 或者其它类似的),注意它们的缺省配置不一定满足这些要求。大多数这类程序有基于菜单的“查看源码”命令,用它来检查发送文件夹中的消息,以确保发送的是没有多余杂质的纯文本文件。

 

描述问题应准确且有内容

 

 

 

  • 仔细、清楚地描述问题的症状

  • 描述问题发生的环境(主机、操作系统、应用程序,任何相关的),提供销售商的发行版和版本号(如:“Fedora Core 7”、“Slackware 9.1”等)

  • 描述提问前做过的研究及其理解。

  • 描述提问前为确定问题而采取的诊断步骤。

  • 描述最近对计算机或软件配置的任何相关改变。

  • 如果可能,提供在可控环境下重现问题的方法。

尽最大努力预测黑客会提到的问题,并提前备好答案。

如果你认为是代码有问题,向黑客提供在可控环境下重现问题的方法尤其重要。当你这么做时,得到有用且及时回复的可能性将大大增加。

西蒙.泰瑟姆(Simon Tatham)写过一篇 如何有效报告臭虫 的文章,我强烈推荐各位阅读。

 

量不在多,精炼则灵

 

 

 

你应该(写得)精炼且有内容,简单地将一大堆代码或数据罗列在求助消息中达不到目的。如果你有一个很大且复杂的测试样例让程序崩溃,尝试将其裁剪得越小越好。

至少有三个理由支持这点。第一,让别人看到你在努力简化问题使你更有可能得到回复。第二,简化问题使你更有可能得到 有用的 回复。第三,在提纯臭虫报告的过程中,你可能自己就找到了解决办法或权宜之计。

 

别急于宣称找到臭虫

 

 

 

当你在一个软件中遇到问题,除非你 非常、非常 的有根据,不要动辄声称找到了臭虫。提示:除非你能提供解决问题的源代码补丁,或者对前一版本的回归测试表现出不正确的行为,否则你都多半不够完全确信。对于网页和文档也如此,如果你(声称)发现了文档的“臭虫”,你应该能提供相应位置的替代文本。

记住,还有许多其它用户并未经历你遇到的问题,否则你在阅读文档或搜索网页时就应该发现了(你在报怨前已经做了这些,是吧 ?)。这也意味着很有可能是你弄错了而不是软件本身有问题。

编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了臭虫,也就置疑了他们的能力,即使你是对的,也有可能会使其中的部分人感到不快。(此外,)在主题中嚷嚷“臭虫”也是特别不老练的。

提问时,即使你私下非常确信已经发现一个真正的臭虫,最好写得象是做错了什么。如果真的有臭虫,你会在回复中看到这点。这样做的话,如果真有虫子,维护者就会向你道歉,这总比你弄砸了然后欠别人一个道歉要强。

 

低声下气代替不了做自己的家庭作业

 

 

 

有些人明白他们不应该粗鲁或傲慢地行事并要求得到答复,但他们退到相反的低声下气的极端:“我知道我只是个可怜的新丁,一个失败者,但……”。这既使人困扰,也没有用,当伴随着对实际问题含糊的描述时还特别令人反感。

别用低级灵长类动物的办法浪费你我的时间,相反,尽可能清楚地描述背景情况和你的问题,这比低声下气更好地摆正了你的位置。

有时,论坛设有单独的初学者提问版面,如果你真的认为遇到了肤浅的问题,到那去就是了,但一样别低声下气。

 

描述问题症状而不是猜测

 

 

 

告诉黑客是什么导致了问题是没用的(如果你的诊断理论是了不起的东西,你还会向别人咨询求助吗?)。所以,确保只是告诉他们问题的原始症状,而不是你的解释和理论,让他们来解释和诊断。如果你认为陈述自己的猜测很重要,应清楚地说明这只是你的猜测并描述为什么它们不起作用。

愚蠢:

我在编译内核时接连遇到 SIG11 错误,怀疑主板上的某根电路丝断了,找到它们的最好办法是什么?

明智:

我组装的电脑(K6/233 CPU、FIC-PA2007 主板[威盛 Apollo VP2 芯片组]、Corsair PC133 SDRAM 256Mb 内存)最近在开机 20 分钟左右、做内核编译时频繁地报 SIG11 错,但在头 20 分钟内从不出问题。重启动不会复位时钟,但整夜关机会。更换所有内存未解决问题,相关的典型编译会话日志附后。

由于以上这点许多人似乎难以掌握,这里有句话可以提醒你:“所有的诊断专家都来自密苏里州”。美国国务院的官方座右铭则是“让我看看”(出自国会议员威勒德.D.范迪弗[Willard D. Vandiver]在1899年时的讲话:“我来自一个出产玉米、棉花、牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。”)针对诊断者而言,这并不是怀疑,而只是一种真实而有用的需求,以便让他们看到与你看到的原始证据尽可能一致的东西,而不是你的猜测与总结。(所以,)让我们看看。

按时间先后罗列问题症状

 

刚出问题之前发生的事情通常包含有解决问题最有效的线索。所以,记录中应准确地描述你、电脑和软件在崩溃前都做了什么。在命令行处理的情况下,有会话日志(如运行脚本工具生成的)并引用相关的若干(如20)行记录会非常有帮助。

如果崩溃的程序有诊断选项(如-v详述开关),试着选择这些能在记录中增加排错信息的选项。记住,“多”不等于“好”。试着选取适当的排错级别以便提供有用的信息而不是将阅读者淹没在垃圾中。

如果你的记录很长(如超过四段),在开头简述问题随后按时间先后罗列详细过程也许更有用。这样,黑客在读你的记录时就知道该注意哪些内容了。

 

描述目标而不是过程

 

 

 

如果你想弄清楚如何做某事(而不是报告一个臭虫),在开头就描述你的目标,然后才陈述遇到问题的特定步骤。

经常出现这种情况,寻求技术帮助的人在脑袋里有个更高层次的目标,他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身有问题,结果要费很大的劲才能通过。

愚蠢:

我怎样才能让某图形程序的颜色拾取器取得十六进制的 RGB 值?

明智:

我正试着用自己选定数值的颜色替换一幅图片的色表,我现在知道的唯一方法是编辑每个表槽,但却无法让某图形程序的颜色拾取器取得十六进制的 RGB 值。

第二种提法是明智的,它使得建议采用更合适的工具以完成任务的回复成为可能。

 

别要求私下回复电邮

 

 

 

黑客们认为问题的解决过程应该公开、透明,此过程中如果更有才能的人注意到不完整或者不当之处,最初的回复才能够、也应该被纠正。同时,作为回复者也因为能力和学识被其它同行看到而得到某种回报。

当你要求私下回复时,此过程和回报都被中止。别这样做,让 回复者 来决定是否私下回答──如果他真这么做了,通常是因为他认为问题编写太差或者太肤浅,以至于对其它人毫无意义。

对这条规则存在一条有限的例外,如果你确信提问可能会引来大量雷同的回复时,那么“向我发电邮,我将为论坛归纳这些回复”将是神奇的句子。试着将邮件列表或新闻组从洪水般雷同的回复中解救出来是非常有礼貌的──但你必须信守诺言。

 

提问应明确

 

 

 

漫无边际的问题通常也被视为没有明确限制的时间无底洞。最有可能给你有用答案的人通常也是最忙的人(假如只是因为他们承担了太多工作的话),这些人对于没有止境的时间无底洞极其敏感,所以他们也倾向于讨厌那些漫无边际的问题。

如果你明确了想让回复者做的事(如指点方向、发送代码、检查补丁或其它),你更有可能得到有用的回复。(因为)这样可以让他们集中精力并间接地设定了他们为帮助你需要花费的时间和精力上限,这很好。

要想理解专家生活的世界,可以这样设想:那里有丰富的专长资源但稀缺的响应时间。你暗中要求他们奉献的时间越少,你越有可能从这些真正懂行也真正很忙的专家那里得到解答。

所以限定你的问题以使专家回答时需要付出的时间最少──这通常与简化问题还不太一样。举个例,“请问可否指点一下哪有好一点的 X 解释?”通常要比“请解释一下 X”明智。如果你的代码不运行了,通常请别人看看哪有问题比叫他们帮你改正更明智。

 

关于代码的问题

 

 

 

别要求他人给你出问题的代码排错而不提及应该从何入手。张贴几百行的代码,然后说一声“它不能运行”会让你得不到理睬。只贴几十行代码,然后说一句“在第七行以后,本应该显示<x>,但实际出现的是<y>”非常有可能让你得到回复。

最精确描述代码问题的方法是提供一个能展示问题的最小测试样例。什么是最小测试样例?它是对问题的展现,只需要刚好能够重现非预期行为的代码即可。如何生成一个最小测试样例?如果你知道哪一行或哪一段代码会产生问题,将其复制并提供刚好够用的外围支撑代码以构成一个完整的样例(够用是指源码刚好能被编译器、解释器或任何处理它的程序所接受)。如果你不能将问题缩小到特定的段落,复制源码并去除那些与问题无关的代码段。你能提供的最小测试样例越小越好(参见 量不在多,精炼则灵 )。

生成一个非常小的最小测试样例并不总是可能,但尽力去做是很好的锻练,这有可能帮助你找到需要自己解决的问题。即使你找不到,黑客们喜欢看到你努力过,这将使他们更合作。

如果你只是想让别人帮忙审一下代码,在最开头就要说出来,并且一定要提到你认为哪一部分特别需要关注以及为什么。

 

别张贴家庭作业式问题

 

 

 

黑客们善于发现“家庭作业”式的问题。我们中的大多数人已经做了自己的家庭作业,那是该做的,以便从中学到东西。问一下提示没有关系,但不是要求完整的解决方案。

如果你怀疑自己碰到了一个家庭作业式的问题,但仍然无法解决,试试在用户组、论坛或(作为最后一招)在项目的“用户”邮件列表或论坛中提问。尽管黑客们看出来,一些老用户也许仍会给你提示。

 

删除无意义的要求

 

 

 

抵制这种诱惑,即在求助消息末尾加上诸如“有人能帮我吗?”或“有没有答案?”之类在语义上毫无意义的东西。第一,如果问题描述还不完整,这些附加的东西最多也只能是多余的。第二,因为它们是多余的,黑客们会认为这些东西烦人──就很有可能用逻辑上无误但打发人的回复,诸如“是的,你可以得到帮助”和“不,没有给你的帮助”。

一般来说,避免提“是或否”类型的问题,除非你想得到 “是或否”类型的回答

 

不要把问题标记为“紧急”, 即使对你而言的确如此

 

 

 

这是你的问题,不要我们的。宣称“紧急”极有可能事与愿违:大多数黑客会直接删除这种消息,他们认为这是无礼和自私地企图得到即时与特殊的关照。而且“紧急”或其它有类似含义的主题有可能触发垃圾过滤规则,潜在的回复者可能永远看不到你的问题!

有一点点局部的例外,如果你是在一些知名度很高、会使黑客们激动的地方使用程序,也许值得这样去做。在这种情况下,如果你有期限压力,也很有礼貌地提到这点,人们也许会有足够的兴趣快一点回答。

当然,这是非常冒险的,因为黑客们对什么是令人激动的标准多半与你的不同。譬如从国际空间站这样张贴没有问题,但代表感觉良好的慈善或政治原因这样做几乎肯定不行。事实上,张贴诸如“紧急:帮我救救这个毛绒绒的小海豹!”肯定会被黑客回避或光火,即使他们认为毛绒绒的小海豹很重要。

如果你觉得这不可思议,再把剩下的内容多读几遍,直到弄懂了再发贴也不迟。

 

礼貌总是有益的

 

 

 

礼貌一点,使用“”和“谢谢你的关注”或者“谢谢你的关照”,让别人明白你感谢他们无偿花时间帮助你。

坦率地讲,这一点没有语法正确、文字清晰、准确、有内容和避免使用专用格式重要(同时也不能替代它们)。黑客们一般宁可读有点唐突但技术鲜明的臭虫报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教我们什么来评价它的)

然尔,如果你已经谈清楚了技术问题,客气一点肯定会增加你得到有用回复的机会。

(我们必须指出,本文唯一受到一些老黑客认真反对的地方是以前曾经推荐过的“提前谢了”,一些黑客认为这隐含着事后不用再感谢任何人的暗示。我们的建议是要么先说 “提前谢了”,事后对回复者表示感谢,要么换种方式表达,譬如用“谢谢你的关注”或“谢谢你的关照”)。

 

问题解决后追加一条简要说明

 

 

 

问题解决后向所有帮助过的人追加一条消息,让他们知道问题是如何解决的并再次感谢。如果问题在邮件列表或新闻组中受到广泛关注,在那里追加此消息比较恰当。

最理想的方式是向最初提问的线索回复此消息,并在主题中包含“已解决”、“已搞定”或其它同等含义的明显标记。在人来人往的邮件列表里,一个看见线索 “问题 X”和“问题 X-已解决”的潜在回复者就明白不用再浪费时间了(除非他个人觉得“问题 X”有趣),因此可以利用此时间去解决其它问题。

追加的消息用不着太长或太复杂,一句简单的“你好──是网线坏了!谢谢大家──比尔”就比什么都没有要强。事实上,除非解决问题的技术真正高深,一条简短而亲切的总结比长篇大论要好。说明是什么行动解决了问题,用不着重演整个排错的故事。

对于有深度的问题,张贴排错历史的摘要是恰当的。描述问题的最终状态,说明是什么解决了问题,在此之后 才指明可以避免的弯路。应避免的弯路部分应放在正确的解决方案和其它总结材料之后,而不要将此消息搞成侦探推理小说。列出那些帮助过你的名字,那样你会交到朋友的。

除了有礼貌、有内容以外,这种类型的追帖将帮助其他人在邮件列表、新闻组或论坛文档中搜索到真正解决你问题的方案,从而也让他们受益。

最后,此类追帖还让每位参与协助的人因问题的解决而产生一种满足感。如果你自己不是技术专家或黑客,相信我们,这种感觉对于你寻求帮助的老手和专家是非常重要的。问题叙述到最后不知所终总是令人沮丧的,黑客们痒痒地渴望它们被解决。“挠痒痒”为你挣到的信誉将对你下次再次张贴提问非常非常的有帮助。

考虑一下怎样才能避免他人将来也遇到类似的问题,问问自己编一份文档或 FAQ 补丁会不会有帮助,如果是的话就将补丁发给维护者。

在黑客中,这种良好的后继行动实际上比传统的礼貌更重要,也是你善待他人而赢得声誉的方式,这是非常有价值的财富。

 

继续阅读提问的智慧

欺骗的艺术

欺骗的艺术

The Art of Deception

凯文•米特尼克著

 

前言

人之初

从盗打电话到黑客

成为社会工程师

最后的想法

内容介绍

第一部 幕后的故事

第一章 安全软肋

第二部 攻击者的手段

第二章 无害信息的价值

第三章 正面攻击——直接索取

第四章 建立信任

第五章 我来帮你

第六章 你能帮我吗?

第七章 假冒网站和危险附件

第八章 利用同情、内疚和胁迫

第九章逆向骗局

第十章进入内部

第十一章综合技术与社会工程学

第十二章攻击新进员工

第十三章聪明的骗局

第十四章商业间谍

第十五章信息安全知识与培训

第十六章推荐的信息安全策略 

附件列表

 

继续阅读欺骗的艺术

Grep学习笔记

Grep学习笔记

整理:Jims of 肥肥世家

第一次发布时间:2004年7月16日


1. grep简介

grep(global search regular expression(RE) and print out theline,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符,fgrep就是fixed grep或fastgrep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

grep的工作方式是这样的,它在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。

grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。

2. grep正则表达式元字符集(基本集)

^

锚定行的开始 如:’^grep’匹配所有以grep开头的行。

$

锚定行的结束 如:’grep$’匹配所有以grep结尾的行。

.

匹配一个非换行符的字符 如:’gr.p’匹配gr后接一个任意字符,然后是p。

*

匹配零个或多个先前字符 如:’*grep’匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。

[]

匹配一个指定范围内的字符,如'[Gg]rep’匹配Grep和grep。

[^]

匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep’匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。

\(..\)

标记匹配字符,如’\(love\)’,love被标记为1。

\<

锚定单词的开始,如:’\<grep’匹配包含以grep开头的单词的行。

\>

锚定单词的结束,如’grep\>’匹配包含以grep结尾的单词的行。

x\{m\}

重复字符x,m次,如:’0\{5\}’匹配包含5个o的行。

x\{m,\}

重复字符x,至少m次,如:’o\{5,\}’匹配至少有5个o的行。

x\{m,n\}

重复字符x,至少m次,不多于n次,如:’o\{5,10\}’匹配5–10个o的行。

\w

匹配文字和数字字符,也就是[A-Za-z0-9],如:’G\w*p’匹配以G后跟零个或多个文字或数字字符,然后是p。

\W

\w的反置形式,匹配一个或多个非单词字符,如点号句号等。

\b

单词锁定符,如: ‘\bgrep\b’只匹配grep。

3. 用于egrep和 grep -E的元字符扩展集

+

匹配一个或多个先前的字符。如:'[a-z]+able’,匹配一个或多个小写字母后跟able的串,如loveable,enable,disable等。

?

匹配零个或多个先前的字符。如:’gr?p’匹配gr后跟一个或没有字符,然后是p的行。

a|b|c

匹配ab或c。如:grep|sed匹配grep或sed

()

分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。

x{m},x{m,},x{m,n}

作用同x\{m\},x\{m,\},x\{m,n\}

4. POSIX字符类

为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating SystemInterface)增加了特殊的字符类,如[:alnum:]是A-Za-z0-9的另一个写法。要把它们放到[]号内才能成为正则表达式,如[A-Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。

[:alnum:]

文字数字字符

[:alpha:]

文字字符

[:digit:]

数字字符

[:graph:]

非空字符(非空格、控制字符)

[:lower:]

小写字符

[:cntrl:]

控制字符

[:print:]

非空字符(包括空格)

[:punct:]

标点符号

[:space:]

所有空白字符(新行,空格,制表符)

[:upper:]

大写字符

[:xdigit:]

十六进制数字(0-9,a-f,A-F)

5. Grep命令选项

-?

同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。

-b,–byte-offset

打印匹配行前面打印该行所在的块号码。

-c,–count

只打印匹配的行数,不显示匹配的内容。

-f File,–file=File

从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。

-h,–no-filename

当搜索多个文件时,不显示匹配文件名前缀。

-i,–ignore-case

忽略大小写差别。

-q,–quiet

取消显示,只返回退出状态。0则表示找到了匹配的行。

-l,–files-with-matches

打印匹配模板的文件清单。

-L,–files-without-match

打印不匹配模板的文件清单。

-n,–line-number

在匹配的行前面打印行号。

-s,–silent

不显示关于不存在或者无法读取文件的错误信息。

-v,–revert-match

反检索,只显示不匹配的行。

-w,–word-regexp

如果被\<和\>引用,就把表达式做为一个单词搜索。

-V,–version

显示软件版本信息。

6. 实例

要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。

$ ls -l | grep ‘^a’

通过管道过滤ls -l输出的内容,只显示以a开头的行。

$ grep ‘test’ d*

显示所有以d开头的文件中包含test的行。

$ grep ‘test’ aa bb cc

显示在aa,bb,cc文件中匹配test的行。

$ grep ‘[a-z]\{5\}’ aa

显示所有包含每个字符串至少有5个连续小写字符的字符串的行。

$ grep ‘w\(es\)t.*\1’ aa

如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用”\”号进行转义,直接写成’w(es)t.*\1’就可以了。


2013年10月15日 10:23:07 星期二 yclimw转载

 

计算机专业学习浅谈

原文出处: 林建的博客


一、广泛了解,从科普书籍开始

选择计算机专业的同学,也许是因为原先有一定的基础,也许是因为一时的激情,但更多的人,可能对自己的选择没有深刻的认识,或多或少对计算机专 业有一些神秘的感觉。自己究竟是否喜欢这个学科?才华能够在哪个分支领域有所施展?抑或是真的不适合这个专业?诸多疑问,解决的方法首先便是了解和认识我 们的学科。浓厚的兴趣是学好任何学科的源泉;而广泛的了解则是获得兴趣的途径。当今我们对于信息的获取已非难事,其中“阅读”是一个简洁而有效的方法。

也许你认为阅读专业书籍对于刚刚步入大学的自己来说有点困难,也很枯燥,那么不妨先从科普书籍看起。科普书籍是了解理论、获得应用知识最好的途 径。相信不少理工科的同学被量子物理和相对论搞得头昏脑胀过。究其原因,是我们的现实生活与抽象的数学模型之间存在思想意识上的鸿沟。然而要是读读斯蒂 芬·霍金的《时间简史》,你就会被书中有趣的故事和例证所吸引,从而对抽象的理论有了感性的认识——即使仍然没有读懂,你也至少了解了这个学科研究的领域 和目标是什么,也必然有所收获。所有理工学科都有这样的性质,计算机专业也不例外。

我们知道,计算机理论是建立在数学基础之上的。大学计算机专业对数学的要求较高,其重要性不必多言。数学令不少同学头痛,除了其“繁”与“难” 外,很大程度上是因为他们没有理解这些抽象理论的实际应用方向。与本科数学专业的课程设置相比,计算机专业的数学课程大都偏重实用性。比如我们的离散数学课程中涉及到的逻辑代数奠定了计算机一切运算的基础,形式语言构成了计算机程序编译的模型,代数系统则是当前各类数据库系统的理论依据等等。因此,如果能够提前地了解到并简单地学习一下这些数学知识的具体应用,对理解理论是很有益处的。此外,电子学、信号与系统、控制理论等也是计算机专业学生必修的公共课,然而不少同学往往认为它们与计算机专业的关系不大,从而放松了学习。事实上这些学科是计算机硬件与网络通信的基础,学好这方面知识的前提是认识它们的现实应用及其与计算机的密切联系。

也许你将来学习图论的时候,对“欧拉路”的概念会很清晰,这是因为你在小时候的图画书上玩过“一笔画”的游戏;然而“二分图”、“生成树”这些概念又是怎么回事呢?你的理解可能就不是那么深刻了——因为你一时难以找到一些生活中的实例,并从中抽取出特性。在这种情况下,翻阅一些涉及这些知识的科普书籍就十分有必要了。我曾读过一套《数学游戏》(《科学美国人》杂志汇编,中文版:科学技术文献出版社),它将图论、逻辑代数、自动机理论等领域的抽象的概念具体化为一个个有趣的故事,引导读者了解这些知识的现实应用,启发读者将抽象思维与感性生活有机结合。我还读过一本《编码的奥秘》(《CODE》, 中文版:机械工业出版社),它则将逻辑代数、数字电路、汇编语言等知识以实物和简单电路的形式进行类比,揭示其中的原理,并引导读者动手实践。事实上这类与计算机专业相关的科普书籍还有很多,在学习课本的间隙阅读一下,绝对能起到催化剂的作用。

谈到科普书籍,相关的另一个问题便是计算机科学与计算机技术之间的关系。也许不少同学选择计算机专业,是源于对计算机令人眼花缭乱的应用的认识。所谓计算机技术,一般是指包括文字处理、信息管理、多媒体、网站建设等在内的计算机应用技术;而所谓计算机科学,一般指数据结构、组成原理、操作系统、编译原理等计算机内部实现机制。前者是计算机在各行各业提高生产力的体现,属于各类职业教育和专科教育的范畴;而后者是研究是计算机本身的理论,是本科计算机教学的重点。市面上大多数计算机书籍与杂志是计算机应用技术方面的,属“技术普及型”,从受众角度来看与科普书籍有着类似的性质。适当地涉猎一些自己感兴趣的应用技术,对培养学习兴趣、增强实践能力、了解业界行情是很有好处的。不过如果确实想在计算机行业长期做下去,仍然应当将主要精力放在对计算机科学的学习方面。毕竟用科学的理论指导实践是大学教育的意义所在。

总之,广泛了解计算机学科基础科普知识,在今后学习具体理论的时候才会少一些盲目,多一些顿悟。

 

二、把握全局,学习计算机导论

当你对计算机学科涉及的领域有所了解后,就应该着手展开专业学习了。初读本专业的教学计划与课程设置,你或许会被诸如离散数学、编译原理、接口技术等生疏的课程名称弄得一头雾水。这些课程都是研究什么的?它们各自与我们面前的计算机有哪方面的联系?要回答这类问题,首先需要把握全局,从整体上认 识计算机科学。

国内高等院校一般都为大一学生开设计算机基础课程。这类课程的受众面广,主要涉及计算机基础应用知识。各种版本的计算机基础教程几乎都以计算机科学导论作为开篇。对于把计算机作为应用工具的其他专业的学生而言,导论只算是“内容概要”,他们往往更注重后面的应用型知识;而对于把计算机作为研究对象的我们,则决不能忽略这类指导性的内容。专门地、有意识地学好计算机科学导论,能够使你对计算机科学有一个大局观,清楚地认识到每一个分支学科的研究领域与重要意义,从而在今后的具体学习中明确方向,加深理解。

依我个人的学习经验,建议初学者阅读一些国外优秀计算机基础与导论教材。与国内大多数讲解软硬件具体使用的同类教材相比,国外教材更偏重以应用为切入点,深入浅出地阐述计算机科学原理。诸如《计算机文化(第8版)》(《New Perspectives on Computer Concepts》,中文版,机械工业出版社)、《计算机科学导论》(《Foundations of Computer Science: From Data Manipulation to Theory of Computation》,中文版,机械工业出版社):前者适合于各种信息类专业的学生或计算机爱好者阅读。该书图文并茂,语言生动,从应用角度出发,广泛涉及计算机软件、硬件、网络的基本原理,同时概述了计算机学科的历史背景与行业现状。随书的光盘中给出了不少影音材料,在学习的同时还可以提高计算机专业英语听说能力。后者在风格上与前者类似,但内容更适合计算机专业学生阅读,被美国不少高校定为计算机专业学生的入门课。它以实例作为出发点,系统地讲解了计算机组成、计算机网络、操作系统、数据结构、算法设计等分支学科的研究领域、基本原理和应用方向,而几乎不涉及晦涩的数学模型与实现细节。阅读此类书 籍,可以在潜移默化中理清初学者对于计算机科学学习的思路。

计算机科学是一个有机联系的整体,每个分支都或多或少地与其它分支存在依赖关系。如果死板地依照教学计划线性地进行学习,往往会遇到知识理解上 的问题。例如算法分析课程与程序设计课程分属理论与实践;组成原理课程与体系结构课程是对计算机系统不同层面的剖析。我们不能简单地找出它们的先修、后修关系,这样难以建立完整的知识体系。因此在把握大局之后,我们仍有必要简单了解一下每个分支学科的基础知识。在这方面,推荐大家阅读《编程卓越之道(第一卷):深入理解计算机》(《WRITE GREAT CODE: Volume 1:Understanding the Machine》,中文版,电子工业出版社)这本书。分开来看每一章节,其内容编排结构与国内高校计算机课程体制相近,涵盖了逻辑代数、数字电路、机器指令、体系结构、存储器管理等方面的基础知识和实现方法,特别是阐明了各个分支学科之间的本质联系。有了这些基础之后,在遇到更高阶的问题时,你至少会明白这个问题应该在哪个分支学科中寻找答案了。

当你有了一定的计算机理论基础,尤其是程序设计基础后,想更加深入地把握计算机科学的脉络,不妨看看这本书:《深入理解计算机系统(修订版)》 (《Computer Systems A Programmer’s Perspective》,中文版,中国电力出版社)。它与《编程卓越之道》系列的共同特点是从程序员的视角观察计算机系统。而这本书作为国外数十所高校的计算机系统导论教材,其组织更加严密,风格更加严谨。它以“程序在计算机中如何执行”为主线,全面阐述计算机系统内部实现的诸多细节。当你在学习数据结构、组成原理和体系结构等课程和时候,翻阅一下此书的相应章节,同时编程实现其中的例子,一定会对课本上单纯的文字型理论有更加感性的认识——原来它们是 这样活生生地存在于我的计算机里的!

正所谓“会当凌绝顶,一览众山小”,从计算机科学全局的高度整体把握其分支学科,在头脑中率先构建计算机科学的整体框架并为其夯实最基层的结构,就能够为你在未来每一步的学习中扫清迷雾,指明方向。

 

三、运筹帷幄,掌握编程的思想

程序设计与开发是计算机学习的一个关键环节,编程能力是衡量一名计算机专业人员素质的重要考核点。这是因为程序是连接理论与实践的纽带,是计算机科学与计算机技术相交融的领域。作为一名计算机专业学生,我们一方面有别于其它专业将计算机作为工具的应用型人才,不能仅仅利用计算机,而要为他人利用计算机提供平台;另一方面我们暂时达不到计算机科学家的水平,不能做出理论研究成果,但能为理论学习铺垫实践基础。因此,只有具备足够的程序设计与开发能力,才能真正体现我们的智慧,同时充分发挥计算机的潜力。

学习编程,首先应掌握至少一门程序设计语言。C语言作为一种语法清晰、功能强大、应用广泛的高级语言,长期以来被国内大多数高校的定为程序设计必修课。全面理解和掌握C语言的脉络的重要意义这里毋庸多言。市面上C语言的教程多如牛毛,但最经典的当数C语言的设计者Kernighan与 Ritchie 合著的权威白皮书——《C程序设计语言(第2版)》(《The C Programming Language》,中文版,机械工业出版社)。书虽不厚,但绝对全面而准确。其语言简洁,例证通俗,实用性强。相比之下国内的一些C语言教材在学习曲线可能比前者平滑,但它们往往以考试为导向,过多地纠缠语法死角,同时大都未遵从ANSI标准。对于计算机专业学生来说,前者能够让我们看到更加严谨与实务的态度。当你的语言功底达到一定程度后,就需要从一个更高的视角来探察语言的本质,不妨看看这本:《计算机程序的构造和解释(第2版)》 (《Structure and Interpretation of Computer Programs》,中文版,机械工业出版社)。它阐述了编程语言本身的机制与实现,同时引入了一门对于大多数中国学生来说不甚了解的语言——LISP。 LISP是很多美国高校计算机专业的入门语言,也是一种结构上与C、Pascal、Java、Basic等完全不同的非冯·诺依曼语言。研读SICP,体味LISP,给你耳目一新的感觉之后更多地可以加深对编程思想本质的理解。

大学的各类程序设计与开发课程旨在培养我们两方面的能力——算法设计能力与应用开发能力。前者偏重计算机科学,后者偏重计算机技术。算法是用计算机思维解决现实问题的理论,具有较强的数学性。算法学的旷世巨著应数Knuth的《计算机程序设计艺术》(《The Art of Computer Programming》,中文版,清华、机工、国防等出版社皆有授权),不过要彻底读懂这个大部头需要相当的数学理论基础与编程实践经验积累。对于初学者,建议首先培养使用常规算法解决小规模问题的能力,并行地提高驾驭语言的水平与抽象问题的思维。针对这个目的,结合程序设计实践一类的课程,可以读读这几本书:《编程珠玑(第2版)》(《Programming Pearls》,中文版,中国电力出版社)、《程序设计实践》(《The Practice of Programming》,中文版,机械工业出版社)、《代码阅读方法与实践》(《Code Reading: The Open Source Perspective》,中文版,清华大学出版社)、《C专家编程》(《Expert C Programming》,中文版,人民邮电出版社)。它们的侧重点各有不同,但对于通过实践来学习算法与数据结构都是很有益处的。

应用开发方面,实践是第一要务,然而高效的实践是建立在科学的程序设计方法之上的。以C语言为代表的结构化程序设计方法是规范的程序逻辑的基础,目前主要使用在系统级开发中,前面所提到的诸多书籍都或多或少有所涉及。而以Java、C++为代表的面向对象程序设计方法广泛应用于实用项目开发, 这方面的经典之作中,推荐阅读Bruce Eckel的《Java编程思想(第3版)》(《Thinking in Java》,中文版,机械工业出版社)与《C++编程思想(第2版)》(《Thinking in C++》,中文版,机械工业出版社)。此外软件架构设计、编码规范与风格、代码除错与质量管理以及软件工程的各类原则在实际项目开发中都是及其重要的,在 具备了一定的编程经验、准备投入一些实际项目开发的时候务必要了解。建议阅读《代码大全(第2版)》(《Code Complete》,中文版,电子工业出版社)这本大而全的软件构建综合性宝典,它在从总体上指导软件开发的各个环节的同时也引入了一些细节问题(诸如 goto的使用)的讨论,引导我们对一些司空见惯的程序设计理念不但要知其然,而且要知所以然。

有一位热衷于游戏的同学告诉我,游戏给予他满足控制欲的空间。但是请放眼看看,游戏的控制范围不外乎一个特定进程中他人预先设定好的一系列数据,并以有限的图像与声音形式体现出来。然而如果你掌握了编程这一强大的武器,就能够面对眼前的计算机游刃有余,在硬件条件允许的情况下尽你所能将控制欲升华为创造力,方便自己的同时造福他人。运筹帷幄,掌握编程的思想,无论走向科学研究或是应用开发,这都将为你奠定坚实的基础!

 

四、理性思辨,体味计算机哲学

Bill Gates对计算机事业充满激情——“每天早晨醒来,一想到所从事的工作和所开发的技术将会给人类生活带来的巨大影响和变化,我就会无比兴奋和激动。”自由软件运动的精神领袖Richard Stallman几十年如一日,将打破知识垄断、共享人类智慧作为己任,带领着数以万计的软件志愿者推动着开源世界的发展。但并非每个计算机业者都能有Gates那样豪迈的气度和Stallman那种坚定的信仰,计算机及其相关技术对于大多数业者来说仅仅是兴趣爱好或者谋生的工具。计算机行业半个多世纪 以来形成了其独有的文化氛围,作为一名计算机专业学生,了解专业文化,体味专业哲学,对于学习和从业都是具有指导意义的。

首先必须承认,计算机世界中存在着形形色色的意识理念差异。诸如微软帝国与开源世界的明争暗斗,不仅仅是一场商战,更多的是两种哲学的搏击。当代大学生多数是在微软Windows光环照耀下认识计算机的。在这种环境下,多接触一些开源世界的事物,对于理解计算机的本质不无裨益。《共创未来:打造自由软件神话》(《Free for All: How Linux and the Free Software Movement Undercut the High-Tech Titans》,中文版,上海科技教育出版社)是一本讲述开源世界发展史的书,你可以从中了解自由软件运动及其领袖人物的传奇故事,从而对GNU、 Linux、OpenSource这些概念蕴生人性化的理解。清华大学王垠的《完全用GNU/Linux工作,摈弃Windows——你我共勉》、兰州大学黄平的《自由,你忘记了吗?》等长篇文章则是国人对开源运动的慷慨陈辞。尽管这些文章常常被指为“偏激”,但没有调查就没有发言权,无论支持还是反对, 客观的认识是第一位的。

其次,我们应该用平和的心态对待知识与技术,衡准专业学习在生活中的位置。一些同学出于种种原因,成为了“先进技术”的追随者:通晓各类流行的编程语言,一有新版本的工具推出立即安装学习,一有新的技术论战立即关注其走向。还有一些同学成为了某些技术的忠实信徒:看准了Java就对.NET的东西置之不理。这些追随者和信徒们往往为突飞猛进的技术所累,以至于有感于学习的空虚。过分追捧技术可谓舍本逐末,死扣某一知识也显得目光短浅。一方面百变的技术离不开计算机科学的本源,在实践过程中深入理解基础知识是关键;另一方面任何技术都有统领其实现细节的思想精髓,观其形不如知其神。我们不妨甩开冗繁的技术,换个角度静下心来读几部计算机文化与哲学作品:

程序人生方面:《编程之道》(《The Tao of Programming》,双语版,电子工业出版社)一书出自一位对东方道家与禅宗思想有着独特理解的美国软件工程师之手,全书由一则则短小而富有哲理故事组成,以类似寓言的形式生动地反映了程序员群体的生活以及计算机文明的演进。闲暇时随手翻阅,即使不能立刻体会到每个故事的真谛,但随着自身阅历的增长,相信你会领悟程序人生的“道法自然”。

设计理念方面:开源软件界的“斗士”级元老Eric Raymond所著的《Unix编程艺术》(《The Art of Unix Programming》,中文版,电子工业出版社)一书,以Unix系统的设计原则为主线,展示了Unix所开启的“KISS”(Keep It Simple, Stupid!)编程文化与思维方式。对于很多干啃千篇一律的课本、禁锢于Windows开发的计算机专业学生来说,这本书一定能够使你眼界大开——“结构化”并非真理,“面向对象”也不是王道;而对于有一定Unix/Linux使用或开发经验的同学,这本书也一定会使你豁然明朗——原来一个程序的设计竟可以如此精巧!

管理哲学方面:对于有志于软件工程,想涉足项目管理的同学,《人月神话》(《The Mythical Man-Month》,中文版,清华大学出版社)这本书就有必要读一读了。它拿真实案例说事,仿佛一部实例化的软件工程课本。如果你在团队开发的道路上陷入了困境,不如参考一下前辈们是如何处理“人”与“月”二者之矛盾的吧。事实上不仅是软件工程,任何事业的成功,往往技术不是关键,社会科学的因素才是埋 头技术的朋友们更应当关注的。

归根结底,计算机的哲学依旧是人的哲学。抛开理念之争议,超越技术的形式,以人为本地认识我们的行业与自身的地位,或许会使将来的发展道路走得更舒心一些。