1 前言

人并非全知全能,工作和生活难免会有各种的疑问,有问题自然可以询问有经验的同事或朋友。

但为了避免一有问题就去问人,给别人造成困扰,更推荐的就是: 自己先搜索,然后再去问人(Do a search before you ask a question)

当然,如果你不想打扰他人,直接问ChatGPT也未尝不可,只是答案的准确性不一定有保证。

如何高效地搜索,缩小搜索的范围,如何快速地检索到答案呢?

那么我来分享一下自己的个人经验:

虽然我认为「搜索并不仅限于使用搜索引擎」,但是「搜索引擎」却是搜索并不可少的一部分。

虽然搜索引擎有很多,但是我基本只用 Google;如果没法使用 Google, 那么推荐使用Bing, 反正百度不在我的推荐之列.

Google 搜索的界面很简单,只有一个搜索框,用户只需要把想要搜索的内容输入进去并回车即可。

比如搜索:「cpp modules」,返回了 7,320,000条结果。


搜索结果太多,我想对搜索内容进行筛选,google 就提供了相当多的搜索指令(search operator)

2.1 时间

cpp modules是c++20 才新增的特性,如果我想按时间搜索下相关的内容,可以使用 :before, :after 指令,后面跟着一个日期:

1
cpp modules :before 2020


可以看到搜索结果变成了185,000条,并且返回的搜索结果都是在 2020 年以前的纪录,这个在查看历史新闻时特别有用,比如看历史合订本。

2.2 站点

如果你只想搜索某个站点,但是这个站点没有提供搜索功能(比如学校或者公司官网),或者搜索质量不够好,那么就可以加上 site: 的关键词, 要求 Google 只返回某个网站的检索结果:

比如我想看下 jetbrains家的IDE 对 c++ 20 Modules的支持程度:

1
cpp modules site:jetbrains.com


又或者,我搜索网站的时候,想把某个网站排除掉, 比如使用中文搜索编程相关关键词的时候,经常会被CSDN 的垃圾内容污染,那么就可以使用 -, 来排除掉某些内容.

1
cpp modules -microsoft


原来排名第二的 Miscrosft 就被过滤掉了.

2.3 社交媒体

如果你想在社交媒体上搜索某个关键词,那么可以使用 @ 后跟社交媒体的名字来进行搜索,例如 “cpp modules @twitter” 或者 “cpp modules @reddit”, 可以把 @ 理解成是 :site 指令的简化版本.

只是社交媒体(social media)的定义比较含糊, Google没有给出具体的说明,但是比较有名的社交媒体都是支持的.

1
cpp modules @reddit


1
cpp modules @zhihu


2.4 文件类型

可以通过 filetype 来指定想要搜索的文件类型,比如想搜索 pdf 相关的内容:

1
cpp modules filetype:pdf


这个在知道书名,想要搜索电子书的时候特别有用.

2.5 关键字匹配

Google 支持若干个关键字匹配的指令:

双引号: “cpp modules”, 精确匹配,只匹配包含"cpp modules"的内容

1
"cpp modules"


搜索结果变成 3530 条纪录了.

  • 星号: “* modules”, 通配符,所有包含 “modules"的内容都会被检索出来。个人觉得用处不大,只会让搜索结果膨胀.
  • OR: “cpp or module”, 匹配包含 “cpp” 或者"module” 的内容, or 可以使用竖线代替 | 个人觉得用处不大,也只会让搜索结果膨胀
  • AND: “cpp and module”, 匹配包含 “cpp” 与"module" 的内容, and 可以使用与符号代替 &


前面提到「搜索并不仅限于使用搜索引擎」,是因为有很多内容,搜索引擎检索不到。

比如在公司内网的信息,Google 再强大,也不可能会检索得到的,因为不公开。

这个时候就可以借助浏览器的 Custom Search能力(Chrome 叫 Site Search, Firefox叫 Keyword Search)。

举个例子,我的老东家用的是代码搜索工具是 OpenGrok, 可以搜索整个事业群的代码,支持多种语言,可以搜索代码的定义,引用,历史记录等。

(下文以同样使用 OpenGrok 部署的开源项目 LibreOffice 的代码为例子)

因为在日常开发的时候,遇到陌生的函数名或者枚举定义,就需要看下他们的定义与实现,看下有没有问题:

比如想看下 contains 这个函数的实现:


或者想看下 Intersection 这个函数的引用,看下其他人是怎么用这个函数的,我也顺便抄下。


一般的步骤是:

  1. 打开或切换到浏览器(Chrome/Firefox)
  2. 打开内网网站链接, 在例子中就是 https://opengrok.libreoffice.org
  3. 点击 Definition 或者 Symbol
  4. 输入或者粘贴想要查询的内容,比如 contains

一套流程下来,大概需要30-40秒,不能说很慢吧,但是起码算不上快。

但是如果使用 Custom Search, 大概可以缩短至 7-8秒, 并且适用于绝对大部分的网站.

首先把查询函数引用的url 复制下来, 观察:

1
https://opengrok.libreoffice.org/search?full=&defs=&refs=Intersection&path=&hist=&type=cxx&xrd=&nn=19&si=refs&searchall=true&si=refs

refs 后面跟着的就是需要查询的内容, 即 Intersection, 将 Intersection 替换成 %s :

1
https://opengrok.libreoffice.org/search?full=&defs=&refs=%s&path=&hist=&type=cxx&xrd=&nn=19&si=refs&searchall=true&si=refs

打开Chrome/Chromium -> 点击设置(Setting) -> 点击搜索引擎(Search Engine) -> Manage search engines and site search -> Site search [Add]

  • Search Engine: OpenGrok Code Search Find Reference(取个有意义的名字)
  • Keyword: csr
  • URL: https://opengrok.libreoffice.org/search?full=&defs=&refs=%s&path=&hist=&type=cxx&xrd=&nn=19&si=refs&searchall=true&si=refs


然后,在Chrome 的浏览器地址,输入 csr, 空格, 再搜索 Intersection, 回车。就可以直接在Chrome 地址栏里面搜索指定网页的代码.


而搜索代码定义,URL 如下:

1
https://opengrok.libreoffice.org/search?full=&defs=Intersection&refs=&path=&hist=&type=cxx&xrd=&nn=19&si=defs&searchall=true&si=defs

只需要将 defs 后面的内容修改成 %s, 再建一个新的site search, 名为 Opengrok Code Search Find Definition, keyword 为 csd, 就可以快速搜索代码定义.

如果想要搜索其他网站,比如公司内网: https://search.xxoa.com/query=Foobar,
只需要把查询内容修改为 %s, 再新建个Site Search 即可。

在老东家,搜索错误码,或者是搜索内网上的文章,我都是这么干的;所以到新东家之后,我也是这么搞的。

3.2 Firefox

Firefox 也提供类似的功能,叫 Keyword Search, 添加起来甚至更方便:

  1. 打开想要搜索的网站
  2. 在搜索框点击鼠标右键,然后会看到一个「Add a Keyword for this Search…」
  3. 修改名字与 keyword



然后,在 Firefox 的浏览器地址,输入 csd, 空格, 再搜索 Intersection, 回车。就可以直接在 Firefox 地址栏里面搜索指定网页的代码.


如果没有右键时没有找到 「Add a Keyword for this Search…」的选项,也可以使用添加书签的方式,手动添加一个 keyword search:


如果使用的是 Mac OS, 那么通过Alfred 插件的 Web Search功能,甚至可以不用手动切换到浏览器,直接就可以进行搜索,可以把搜索流的耗时进一步缩短到1-3秒。

Alfred -> Preference -> Web Search -> Add custome Search


除了要将 %s 换成 {query} 之外, 其他添加的步骤与 Site Search 一致:


录制 Gif 只花了1.5 秒.

5 总结

Perl语言之父Larry Wall 有句广为人知的名言:「程序员要有三大美德:急躁,懒惰,自大」。

  • 急躁意味着不愿意花时间等待缓慢的程序,会想办法优化程序;
  • 自大意味着不愿让人指谪,对自身要求强,要写出高质量的代码;
  • 懒惰意味着不想花精心做重复无用的事情,会想办法自动化,让电脑帮忙处理。

“We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris.” – LarryWall

而我对搜索流的优化,就是在培养「急躁」与「懒惰」的美德。

6 延伸阅读

我的各种「流」:

7 参考