如何使用google解决问题

Posted redguardtoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用google解决问题相关的知识,希望对你有一定的参考价值。

如何使用google解决问题

redguardtoo

2004/07/07

本文介绍了使用google解决难题的一些高级技术,重点讲述了如何选择关键字,如何分析过滤信息等等。


1. 声明

请读者不要使用本文所介绍的技巧从事违法、不道德的事情。我对于本文所导致的任何后果概不负责。


2. 本文所面向的读者

本文介绍了使用google解决难题的一些高级技术,重点讲述了如何选择关键字,如何分析过滤信息等等。通过阅读本文,你会明白在极大的时间压力下快速解决高难度问题的技巧。你也能了解如何对一些复杂的问题进行调查并给方案。任何对解决问题有兴趣的人都适合阅读本文,只要:

你不相信“软件蓝领”的说法。你相信解决问题的能力是人的本能。你相信任何问题的本质都是一样的。你相信解决问题需要的能力是想象力和举一反三的能力。

说的明白一点,我希望读者是有职业荣誉感的工程师,或者是能够理解这种荣誉感的人。有些人害怕自己即将被技术的进步所淘汰,于是试图通过贬低技术人员的地位来获得安全感。由于他们不能否认技术所取得的伟大成就,于是使用一些政治手腕来间接地达到目的。最常用的手段就是虽然技术是伟大,但是工程师是分等级的(是不是封建残余思想作怪?),低级的工程师就是蓝领,而中国需要的是大量的蓝领,等等。这种有封建残余思想的人是不可能学习新东西的,当然也不可能理解本文,因为要成为google高手,就必须具备开放的头脑和丰富的想象力。


3. 如何使用google解决各种问题

3.1. 不可能完成的任务

一个中国公司的项目组的主要工作是测试一个日本的项目组用C语言开发的系统(调试器为gdb)。一次日本程序员遇到了一个奇怪的问题,当他们用gdb调试时,程序会突然退出。这些程序员研究了两天两夜,不能找出原因。于是他们把退出前调试器上显示的一段错误信息email给中国小组。要求这个小组找出原因。

这个组的组长要我帮忙。我看了错误信息,用到了我不熟悉的进程间通信技术。我首先要求重现错误。“无法重现,因为不知道程序是在哪崩溃的,而我们这也没有运行环境”,回答的斩钉截铁。我要求看源代码。组长告诉我,可以给我看的都是旧代码,出问题的代码早更新过几个版本了,中方暂时还拿不到新代码。说白了,就是没代码。我告诉组长,在这种条件下要解决问题是不可能的。但是领导的意思是利用手头的信息,争取当天解决。

让我小结一下。无法重现错误,没有源代码,不了解相关技术,无法定位bug的大概位置,开发者自己花了两天两夜也无法找出bug原因。而我只有一小段错误信息,除此之外连系统干什么的都不清楚,并被告知不要指望进一步的帮助了。我该如何解决这个问题?

在读者解答这个问题前,我给点提示,日本程序员都是有经验的,他们肯定已将错误信息用google翻了个遍。

给出这个问题的答案花了我15分钟时间。这15分钟时间内我没有读任何文档或者代码。在说明答案前,让我先试着给出思路。我猜日本人已经查过相关的技术手册了,所以我没有必要读手册。给我的信息有限,是因为日方只能提供这些线索。现在看看给我们的一段错误信息是什么?无非是程序退出时,调试器gdb打印的一些信息。例如退出的进程收到了什么信号,该信号是哪个进程发送的等等。我的下一个假设就是日方已经google过这些信息,所以我也不能从这些信息中挖出什么东西了。

要解决问题,就必须发挥想象力,做日本人“没有做过的事情”。日本人没有做过什么?我猜没有做过一件事情,那就是google一下冗余信息。gdb显示错误信息的时候,会以一定的格式显示,比如若干个空格加个冒号什么的。现在我将这些错误信息随机取出一行,这一行既包括了有用的信息,也包括了冗余的信息。我在这一行的内容前后加上双引号,以告诉google尽可能严格匹配该行。然后以此作为关键字google到了答案。答案来自于gdb的一个mailing list,gdb的开发者解释说这是gdb的一个bug,该bug在特定条件下使用特定版本的gdb调试才会发生。

事实上当时我根本没有做如上的分析,接到任务后我做的第一件事就是google冗余信息。这是我的习惯。冗余信息和有意义的信息一起检索的好处是可以快速定位到有同样问题的人。缺点排除了一些有用信息。例如我现在检索gdb的冗余信息,就排除了使用别的调试器的人。好在internet上信息实在是太丰富,过滤掉有用信息不是问题。真正的的问题是从无用信息中快速定位有用信息!


3.2. 如何快速解决具体技术问题

一些“聪明人”相信,只要有某种“伟大、正确”的思想(比如某种“大法”)的指导,任何难题都可以摆平(摆平的方法就是背诵一下伟大思想中的某些特别棒的词)。没有这种信仰的人,只是愚昧无知的小爬虫。“聪明人”解决问题很简单,对问题大面上讲一讲,再念一下咒语。本文是由我,小爬虫中的一条写的,小爬虫不能理解伟大的思想。我解决问题采用和“聪明人”相反的方法。就是从不起眼的细节入手,发挥想象力,举一反三。这个过程中“伟大、正确”的思想连影子也没有出现。

最近我接到了一个任务,要求实现一个扫描给定目录下的文件的模块。问题的难点是这个模块作为一个共享模块(shared ojbect),必须知道自己的物理路径。由于运行平台是Linux,并没有直接支持这种功能的API函数(和Linux应用程序的部署规范有关系)。现在如果我必须实现该功能,该使用什么关键字搜索?

最直接的想法就是google“get shared object path linux”。得到的都是如何在Linux下开发共享模块的文章。增加其他关键字,例如“shared library”,“physical path”,结果也差不多。这个问题的难点不在于选择足够多的关键字以过滤出需要的信息,而是根本就没有信息可以过滤。之所以没有信息可以过滤,是因为Linux有自己的应用程序部署规范(例如配置文件应该放在/etc目录下,可执行文件放在/usr/local/bin目录下等)。如果遵循了这种规范,就没有必要知道共享模块的物理路径了。通常获得共享模块的物理路径是为了由该路径推算配置文件的路径。

最终问题还是被我解决了。我使用了什么关键字?答案很简单,既然正面攻击无效,就旁敲侧击。想一想,如果运行平台是Windows,如何实现该功能?Windows下通常用“GetModuleFileName”API实现。如果有些程序员要把Window的程序移植到Linux下,他(她)该拿GetModuleFileName怎么办呢?答案出来了,google“GetModuleFileName linux”。搜索结果第一条标题是“Qt-interest Archive - location of the program i am running”,就是关于如何获得一个可执行文件的路径的。分析一下google第一页的搜索结果,发觉有一些干扰信息(如何判断干扰信息我将在后文说明)。这说明我们需要稍微修正一下关键字。google“GetModuleFileName +linux”(这里的加号表示linux作为关键字必须出现在搜索结果中)。搜索结果第17条标题为“Guide to Making Relocatable Applications :: autopackage”,这就是标准答案了。

可以看出,解决问题的关键有两个要素。第一个要素是相关的背景知识。作为业内人士,我知道很多公司和个人正在将Windows平台下的软件移植到Linux上。我也知道Windows下如何获得全路径。第二个要素,结合背景知识发挥想象力,通过一些有特点的细节搜索到正确的答案。“GetModuleFileName”就是细节,我想到了可以把这个词和“linux”结合在一起搜索。

让我再举几个例子,说明如何从细节入手,找到问题的答案。

如果我要找VB(Visual Basic)语言写的源代码的话,我会加上“"end sub"”关键字,因为这个关键字是VB的语法特有的。如果我要找C/C++代码参考,我会加上“CVS”作为关键字,这是因为很多开放源代码的项目都是用C或者C++写的,而这些项目都是用CVS作为版本服务器,并用CVS服务器的插件公布到网上的。VB语法和开源软件,这是我的背景知识。但具有相同背景知识的人不一定能找出关键字来。重要的是观察。观察VB的代码,观察开源软件的主页,发挥想象力,从细节中提炼出关键字。

读到这里,读者是不是有点开窍了?解决问题分两步走。首先要有背景知识。然后是发挥想象力,将看似无关的细节结合起来,提炼出关键字。


3.3. 如何解决复杂抽象的问题

一些复杂抽象问题不可能快速找到答案。但是只要方法正确,这些问题最终还是可以使用google一步步解决。步骤是这样的。首先你对问题进行一般描述,从描述中取出关键字google。接下来阅读google的搜索结果,选出有价值的文章。然后从这些文章中分析出有代表性的关键字,继续搜索,阅读结果。重复以上步骤。要注意的是,关键字不应冷门,因为相对于问题的复杂性和抽象性,你的背景知识是不够的。搜索、阅读、搜索的步骤重复多次后,应该对问题有所了解了。在尽可能多地收集资料后,现在可以得出一个初步结论(不要忘记收集不支持该结论的资料)。下一步可以从大问题中提炼出小问题,使用前述的技巧解决小问题。这样做的目的是获得对大问题的切身感受,不是试图解决大问题本身。关键是多角度收集资料。资料不应是相互证明的,最好是互相冲突的。我再强调一下,由于问题的复杂性和抽象性,不要期望在短期内使用特殊技巧解决问题。有了结论,有了支持和反对的资料,又做过一些小的试验,你下一步要做的就是将结论,资料,试验结果提交讨论(超人可以光速飞行,你不可以)。就个人能做的工作而言,你做到这里就不错了。从问题本身来说,复杂抽象的问题的真正的解决,需要许多人长时间地讨论和试验。

下面我讲给出演示,说明这类问题如何着手。

我们以“软件开发行业的新手应该学习什么编程语言,如何学习”为例。如前文所说,应该选择一般描述的关键字。所以我建议你不要把和编程语言有关的关键字加入,而是应该选择如何学习编程的关键字。“how to”就是中文的“如何”,是老外技术文章最爱用的标题。(题外话,“how to”是我个人的王牌关键字)。“learn programming”的中文意思就是“学习编程”。加上前面所说的“how to”,完整的关键字为“"how to" learn programming”(注意:how to 前后的英文双引号表示将how to这个词组作为一个词来搜索)。

现在我们看一看搜索结果。搜索结果第五条“Teach Yourself Programming in Ten Years(十年才能学会编程)”就是一篇很好的文章,介绍了学习编程正确的态度和方法。其他的还有诸如“How To Pick A Programming Language(如何选择编程语言)”,你应该比较感兴趣吧。还有诸如“How To Become A Hacker(如何成为黑客)”,这可是一篇经典文献啊(这里的黑客是指优秀的程序员)。其他的还有“How to Get Started with C++(如何开始学习C++)”,“Instant Hacking : Learn how to program with Python(如何使用python编程)”,“How Java Works(java是如何工作的)”,“How C Programming Works(C是如何工作的)”,“How to Program Perl(如何学习Perl编程)”,“How to: Learn Visual Basic Programming(如何学习Visual Basic编程)”等等。

关于《Teach Yourself Programming in Ten Years(十年才能学会编程)》这篇文章,有必要再谈一谈。希望你不要被这个标题吓住了。让我告诉你一个小秘诀,关于如何判断选对了关键字的秘诀。作为初学者,你不了解软件开发,就象我不了解如何导演电影。所以,也许你自认为没有能力分析搜索结果。有一个办法可以帮你在初次搜索的时候作出正确的判断。作个初学者,你会自认为对软件开发的“常识”和流行趋势还有点了解,例如你认为好程序注释多,例如你认为编程可以在21天你速成。这可能是一种偏见,google是没有偏见的。如果你自认为使用了正确的关键字,google的结果却都是一些和你的“常识”唱反调的文章,说明了什么?说明你选对了关键字。

假设你选好了几种编程语言,现在该是了解那些语言的缺点的时候了。老外对于某种语言和某种文化最爱用的批评语就是“is dead(要玩完了)”,例如“C++ is dead”。现在就让我们google“C++ "is dead"”(注意:is dead 前后的英文双引号)。搜索结果有点出乎意料?搜索结果竟然大都是“Java is dead”,这不表明Java就是一种很差的语言,进一步的结论需要阅读搜索结果。现在我们调查的编程语言是C++!让我们实行更严格的关键字匹配,google“"C++ is dead"”(注意:C++ is dead 前后的英文双引号)。终于得到相关的文章了。这些文章不仅讨论了C++,对于你选择其他编程语言是很有帮助的。例如标题为“khakipants: things to learn”的文章就讨论了学习OCaml和Ruby的必要性。让我们再试一试其他编程语言(这样多来几次你爱上了搜索),google“"Visual Basic is dead"”,google“"Perl is dead"”,google“"html is dead"”。

最后,你终于决定要学习一种语言,比如C++,现在就是了解一下关于C++有哪些工具和资源的时候了,直接google“C++”。


4. 如何提高自己的搜索能力

4.1. 态度决定一切

前面介绍了如何选择关键字解决问题的技巧。接下来要详细论述一下如何获得这些技巧和如何进一步提高搜索水平。由于这些论述都是基于我的经验和体会,肯定有很多偏颇的地方。如果读者有什么更有效的方法,请务必让我学习(我的email见本文开始部分)。

要成为google高手,首要的是态度。“态度决定一切”。如果你相信google是解决问题的强大工具,你喜爱,崇拜google,你就有可能成为google高手。一种比较天真的想法是,“因为google太强大了,所以不应该用google”。其动机是,工具太强大,人就会依赖工具而丧失了某些技能。我认为,人(当然也包括程序员)的价值,在于人的智力,感情,道德。所谓技能,只是上述抽象品质的灵活运用而已。学习新工的好处远不是提高了效率这么简单。真正的好处是获得“原来可以这样做”的启发。死抱住旧工具的人不能获得安全,他们的结局是被潮流淘汰。例如当坦克刚出来的时候,出身于骑兵的巴顿将军毫不犹豫地拥抱坦克这种新的战争工具,最后成为装甲战术大师,名垂青史。担心自己丧失技能的波兰骑兵被纳粹德国的装甲师屠杀于战场之上。技术人员真正重要的技能,是识别新技术的价值的洞察力和使用新技术的行动力。。


4.2. 疯狂搜索法

有了热情,要成为google高手轻而易举。你需要的只是练习。接下来我要介绍练习的办法。和一般人的想法不一样,我不认为“为了特定问题猜关键字”这件事情本身可以作为一种练习手段。我推荐名为“疯狂搜索法”的练习方法。方法很简单,找一篇有趣的文章,将它的字、词、句以各种方法搜索一遍。试着分析搜索结果,(分析方法在后文有详细描述),要有一个好或者不好的结论。好的定义是提供了有用的信息。

让我举个例子。我“疯狂搜索”一下标题为“软件商对用户的角色扮演”的文章。首先google其标题“软件商对用户的角色扮演”。搜索结果有两页,可以看出该文原始出处为ChinaByte。接下来再google作者“老单”,从搜索结果看,标题为“老单:三说软件从业者”的文章似乎也是同一人所写。但是叫老单的人好像多了点。例如标题为“老单和他的6+1彩票预测术”一文中的老单不是我们要找的人。google“老单 软件”以过滤垃圾信息,可以看到“浅析作坊式开发”,“软件企业里的官儿”等文也是其写的。只要将这四篇文章放在一起分析。一切都很明显了。老单谈的都是个人体会,文笔流畅。现在该做结论了了。我的结论是老单提供的都是真实的信息,结论是好。

接下来我们google文中的单词。以第一句“软件企业以盈利为目的进行生产经营和产品销售,自然地被称为软件商”为例。google“生产经营”得到诸如“中国农业银行---贷款业务个人生产经营贷款”之类的文章,分析下来该词较书面化,多出于政府公文,新闻等等。“生产经营”象一个大词。google“产品销售”,得到结果多是各企业网站的产品页面。如果将该词和别的词组合,似乎可定位到企业网站的特定页面。篇幅有限,我就分析到这了。最后让我举出文中出现的两个词,“受众需求”和“漫天吹起”。“受众需求”显然是用于新闻广告行业的术语。“漫天吹起”的搜索结果只有两条,一条就是我们正在分析的文章,另一条是“圣剑传说Ⅲ”。


4.3. 如何提高“搜索素养”

“疯狂搜索法”只是入门练习。要成为专家,关键是提高“搜索修养”。搜索修养体现为快速过滤掉无用信息的能力和定位有用信息的能力。实际工作中碰到的问题是通过多次“深度搜索”才得以解决的。“深度搜索”的意思是,第一次搜索得到的结果必须由人来阅读和分析,然后以分析的结果进行下一次搜索,依此类推。我的经验是,较难的问题往往需要进行几十此搜索才能找到正确答案。如果慢慢读每一条信息,非常累人。

搜索修养的根本办法是大量阅读各种非技术类书籍(技术类书籍读起来有点累)以及进行适当的写作训练。这个问题本身可以写成一篇文章,本文由于篇幅所限无法展开。这里只提供我的一点心得。

过滤搜索结果的关键是两点,“信用(credit)”和“风格(style)”。

所谓“信用”,就是提供信息的人的本身的可信度如何。说白一点,就是他(她)是否以前做过相关的比较优秀的工作。例如,因为我读过John Robbins写的《应用程序调试(Debug Application)》,所以在调试技术方面我非常信任John Robbins。由于信用是可以延伸的(所谓爱屋及乌),John Robbins的文章中引用到的资料的作者在我的心目中也是大师。反过来说,那些提到John Robbins名字的文章的信用也要比没有提到的信用要高。这里有个陷阱,提到过于出名的大师的名字不一定是好事。有些大师太有名了,以至一些不学无术的人会大量引用他们的名字或者文章以掩盖自己的贫乏。例如,提到“linus”名字次数多的关于linux的文章并不一定有多少价值。某些世界级的开源项目的骨干程序员在也是有信用的。上述标准对我够用了。因为我水平有限,对于行业内的专家了解不多,所以我需要坚持高标准。这个标准就是,全世界范围内有影响的项目,书,人才算有信用。

有时搜索结果不都能和大师联系起来。例如提供资料的人是某个“技术工作者”。这时我觉得不应从“信用”的角度来判别了。有些人会从国籍,种族,性别,年龄,工作过的公司乃至上过的中学的名字来判断作者的信用,再推论文章的价值。这种方法有歧视的味道,也不可靠。我倾向于从“风格”出发。内在的风格是是无法掩饰的。例如我姐姐虽然工作只是起草简单的公文,但她总不会忘记在文中加入几个“文雅”的词,以显示中文系没白读。

对技术人员来说,风格的判断结果是很简洁的,“好”或者“坏”。为了得到这个结果,需要一些指标来。接下来我就非常简略地谈一谈这些指标。由于我的无知和偏见,再加上篇幅有限,这些指标肯定有很多漏洞。请读者对我抱有宽容之心。

标题是否言之有物。

正文是否旁征博引,夸夸其谈?

正文是否有实例,有数据,有完整的因果关系?我这里强调一下,因果关系“完整”是很重要的。技术文章的作者把推导的默认前提写下,因果关系就是完整的。什么是默认前提?在电影《伊丽莎白》中,辅佐伊丽莎白一世的大臣罗伯特对她说:“作为女王,您必须...”。罗伯特这样说的默认前提是,他认为年轻的女王没有能力独立统治英国,女王和自己的关系是学生和老师的关系。在电影的最后部分,伊丽莎白直接驳斥了这个从没有说出口的前提,“‘必须’这个词不是能对一个女王说的。...我是我父亲的女儿。...从今以后,我将自己作出决定...”。

为读者考虑(considerate)。例如要给出被引用资料的详细来源,便于核查。

是否使用权威或者命令式的口吻。使用这种口吻,要么才华横溢或者虚张声势。需要结合其他指标一起核查。

有否奇谈怪论?在较一般抽象问题上的奇谈怪论往往有道理。具体问题采用奇谈怪论会有风险。

类似的指标很多,没法一一列举。说到底,只要多读书,这种指标你也可以归纳出来。熟悉文章风格的入门读物,我推荐《The Elements of Style》(有中文版,《英文写作指南》,陈一鸣译,上海译文出版社)。该文的电子版也可以找到(你应该在读到这句前就google过“The Elements of Style”了吧)。

以上是关于如何使用google解决问题的主要内容,如果未能解决你的问题,请参考以下文章

如何维护两个google-services.json,生产和调试

如何停止或禁用 Google App Engine 生产服务器?

Android:Google FCM 规范 ids - 如何在非生产或测试中重现

如何将 google play 和 testflight 中的 beta 用户转移到生产应用程序

为啥 UnhandledPromiseRejectionWarning 只出现在生产中(Google Cloud Run)?

转载如何完美使用Paxos算法,服务生产线上的大规模集群?