跳到主要内容

向卓有成效的程序员迈进

提高工作效率的想法

工作中经常需要做一些重复性很高的任务。这些任务手工去做没有太大的难度,也不涉及任何思考,简单的去做就能够完成。话虽如此,可每当你手工去做的时候,还是难免厌烦,需要忍一忍才能过去。不过如果在重复的过程中因为一个疏漏而搞错了一些步骤,没有及时发现的话可能会给未来埋下一个引雷。

如果你在未来的某一天突然遇到了一个诡异的问题,然后经过辛苦的调试,最终发现是之前在做那些重复性任务时疏漏了一些东西所致。你在抱怨的同时,会不会想到这个问题可以在最开始的时候就能避免呢!你可能会想我根本就不应该去做这些重复性很高的事情,领导应该派给我更有挑战性的任务,而这些简单的任务就交给其他人去做吧。有这样想法的人可能并不少见,这也很正常。可是如果我们能够从另一个角度去看待这个问题,那么或许会得到很不一样的结论。

换一种思考角度

实际上,领导所分配的任务一般都是相对较大的任务。当我们着手去做的时候,我们可能会发现其中包含着许多小任务。重复性高的任务可能正是这些小任务中的一个。如果你又开始抱怨,那么我想你可能需要一直抱怨下去!其实如果你仔细的分析一下这些重复性高的任务,你可能会发现你完全可以不用手工去完成,你可以设计一个中间的媒介,让这个媒介来执行手工执行的过程,而你的任务现在变成了如何实现、寻找到一个合适的媒介。

问题变了吗

这里的思考从表面上看好像是以不同的角度分析问题,实际上却是我们对重复性的问题有了更深入的了解。我们能够发现这里涉及的重复性反映出的一类问题的相同模式,能够看到这个模式并去实现,我们就能够解决一类问题。当解决了很多这样的一类问题之后,我们可以进一步思考我们在每次解决一类问题时是否也存在类似的模式。能够看到这样的模式就表明我们的思考进入到了一个更高的层次。

我将这一模式的具体过程描述如下:

  1. 观察不同类问题
  2. 发现不同类问题的相同模式
  3. 解决不同类问题

虽然上面已经描述了该模式的具体过程,可是第三步不容易解决。

进一步的推广我们甚至可以说我们思考本身就有着固定的模式,只是这个模式很难发现。即便我们能够发现这样的模式,又怎么去实现它呢?

对思考本身模式的思考就此打住!

我们可以发现上面我对重复性问题的描述表明此问题可能有多个不同的层次。当我们发现并解决了第一层的重复性之后或许能够看到更高一层的重复性。在这样的过程中我们对问题本身有了更深入的认识,却可能很难看到,更遑论去实现相同的模式。不过即便仅仅解决低层的重复性问题,我们的工作效率也能够有很大的提升!

提高工作效率的做法

当你有了提高工作效率的想法之后,要真正以行动来达成需要不断的尝试。你需要仔细的观察并思考工作中遇到的各种问题,发现重复性并不断尝试消除重复性。

编码中的重复性

在编写代码的过程中,你发现了重复性,可以通过抽出通用的函数来复用代码。 一般当你复制代码时,你很可能正面临着一个消除重复性的机会。不过有时候这样的工作并不容易,抽象出通用函数的复杂度可能会让人难以接受。这时你可以选择使用重复的代码,这样可能效率更高。

对于不可避免的重复代码,你如果不能通过重新组织代码的逻辑性来减少重复,你可以尝试使用一些间接的方法。如果你听说过代码生成器这个东东,也许便能够很方便的解决问题。

代码生成器

代码生成器的功能与其字面意相同,指的是能够用来生成代码的工具。简单的代码生成器实质是一系列的字符串处理所实现的。虽然这样说,但实际写起来之后,你会发现它可能涉及到了很多细节,并没有表面上看上去那样简单。

表面来看代码生成器实现了一套生成代码的模板,深入的来看它其实实现了一套生成固定格式字符串的模板。当你需要使用代码生成器时,你传递参数来用这些模板对解析后的输入参数进行封装便能够得到新的字符串,这些字符串就是最终生成的代码内容。实际上,对用户而言,使用这些代码生成器仅仅需要按照其内部规定的格式传递输入参数即可。可对于实现者而言,可能需要对输入参数进行解析加进一步的处理。这个解析工作的复杂性将直接影响到整个代码生成器的复杂性。

对于简单的代码生成器来说,它的输入的格式也相对简单。解析这种简单的输入格式当然相当容易。可如果输入是一段代码呢?解析这段代码的过程就不像前一种那样容易了。尽管一种语言的 parser 也有很多的方式来实现,但是其复杂性相比简单的输入格式要高很多。

不过你不用太担心。这种需要解析代码的情况很少发生,大多数时间内我们只需要编写简单的代码生成器就能够完成任务。不过如果你足够强大,你完全可以掌握这种方式,这就是所谓的杀手锏吧!

寻找一个文件的重复性

在图形界面中要寻找一个文件的位置时,我们常常会打开文件资源管理器,然后重复执行点击某一目录,查看子目录与文件,继续点击子目录,查看子目录中的目录与文件的过程直至找到文件。有时你可能也会用用系统提供的查找文件的功能,可是即便使用了这个功能,你可能仍然需要花很长时间来等待搜索完成。

检索文件相关工具需要提供的功能

其实我们完全可以使用一些高效的工具来快速的定位文件的位置。这些工具不仅要提供快速的查找功能,更可以进一步扩展查找的方式,如引入正则表达式来查询等等。如果你不以为然,那么请你想想当你仅仅能够记得一个文件的部分文件名时,你怎么快速找到这个文件呢?

快速检索文件位置的原理

这些快速查找系统中文件的工具,其实现原理大致是首先扫描磁盘分区,建立当前磁盘分区完整的文件、目录数据库,然后以不同的搜索方式检索数据库即可快速的定位到文件。实际上这些工具在工作的时候并不会频繁扫描分区,一般需要你主动指定它们去更新,或者在工具内部按照默认的行为扫描分区。

常用的检索文件位置工具介绍

1. windows 系统

windows 上使用非常广泛的 【everything】 就是这些工具的一个实例。它会在程序运行后立刻开始扫描分区以重建、更新数据库。这之后在使用中都不会再次扫描分区,除非你重新启动程序。

它支持大小写敏感匹配、全路径匹配、正则表达式匹配等功能,能够帮助用户快速的定位到文件位置。

2. linux 系统

linux 中类似的工具是 locate 命令。这个命令也是通过检索数据库来查找文件的,更新数据库则需要使用 updatedb 命令。locate 命令也支持大小写敏感匹配、全路径匹配、正则表达式匹配等功能。除此之外,它还支持万用字符匹配。对于可能存在的文件在数据库中存在,在文件系统中不存在的问题可以通过指定 -n 参数来让 locate 仅仅输出真正存在的文件。

处理多个文件的重复性

在工作中我们常常需要处理文件。这一过程可能包含修改文件、移动文件、重命名文件等等。有时我们需要以相同的操作方式来重复的操作不同的文件。使用图形界面完成这些任务时,我们一般需要鼠标与键盘协同来完成。当文件的数量很少的时候这样的操作很快便能结束,可当文件的数量很多的时候,可能要点来按去很长时间才能完成工作。这既无聊且低效。如果你熟悉命令行,那么使用命令行的工具来完成可能会有很大的不同。

命令行工具的使用难度一般来说要比图形界面高一点。一些命令还有着较为陡峭的学习路线,这个可能是一个比较高的门槛吧。可当你熟悉命令行的使用之后,你可能会暗自庆幸。

linux 三剑客

熟悉 linux 系统的朋友可能曾经听说过 linux 三剑客的大名。这三剑客代表了三个功能强大且十分常用的命令——grep、sed、awk。这三个命令都支持基础正则表达式与扩展正则表达式,简直可以称得上是利器中的利器啊!

grep 主要用于在文件中检索内容,有很多参数扩展了检索的功能。sed 功能更多点,它可以增删改查,基本上大部分语句都离不开正则表达式。awk 功能更多,它完全可以用来实现 grep、sed 的所有功能,毕竟它是一门相对完整的脚本语言。不过一般很多书籍里面都会说 awk 主要用于字段处理。这其实不过是 awk 中的一部分内容而已,它的水还是相当深的,我就经常用它来写一些简单的代码生成器。

grep 与 sed 的那些简单操作还是容易学习的,不过那些压箱底的东西还真的有一定的难度。awk 作为一种脚本语言,设计中存在的一些问题让它的学习也并不轻松。不过抛开学习成本不谈,这三个工具确实能够极大的提升工作效率。

我对三剑客的反思

不过最近我的看法有些变化。我觉得这些工具虽然好用,但是不利于进一步的学习。正则表达式让这些工具变得非常强大,可它也存在着一定的危险,可能会导致不可恢复的结果!用这些工具来解决问题的核心变成了想一条、多条正则表达式。这样的方式颇有投机取巧的意味。其实我们完全可以使用高级通用语言来解决类似的问题,这样我们的编程思维便能够得到很好的提升。不过对那些分分钟便能用这些工具完成的任务,用这些工具完成更高效一点。

在这样的思考下,我得出了下面这样一条规则:

对于几秒钟、几十秒钟就能想到解决方案的情况,直接使用命令行工具。对于需要花几分钟甚至更多时间来想到一个解决方案的情况,使用通用语言编码完成。

命令行 vs 图形界面

命令行与图形界面是两种操作系统的不同方式。他们在不同的环境中能够带来的效率提升是不同的,不能一概而论。尽管有这样的立论,可图形界面为了方便用户使用确实隐藏了诸多工作细节。对于那些能够通过了解程序工作细节来提升效率的情况,图形界面的操作便无法做到。这时你可以考虑使用命令行。

命令行提供了很多的小工具。每种小工具基本都是一类问题的解决方案。你不仅可以使用单个命令来完成简单任务,也可以将命令组合起来以完成更为复杂的任务。

可以说如果你对命令行掌握的很好,那么你的工作效率将会得到极大的提升。可是我们不得不承认的是命令行的学习成本可能要比图形界面高很多,这也就意味着一开始你不仅可能看不到效率的提高,而且可能会花费你更多的时间。可一旦当你熟练掌握命令行的使用,那么未来的工作中它能够发挥出很大的作用,这样前期的付出就得到了回报。

写一门新的语言来提高效率

有时甚至可以考虑编写一门新的语言来提高工作效率。这里提到的语言并不是通用的程序语言而是领域语言。这种方式算是前面几种做法中难度系数最高的了。可其实如果你对一门语言的实现有基础的了解,你会发现它可能并没有那么困难。只是你必须仔细考虑是否有必要设计出一门领域语言。大多数时间中,你完全可以使用现有的通用程序语言完成功能,不必创造一门新的语言。

快捷键的使用

快捷键的使用对于提高效率也有很大意义。鼠标操作的方式看似方便,其实却不利于效率的提高。快捷键虽然能够在一定程度上提高工作效率,却需要记忆,不像鼠标操作那样简单。

自动化处理

对于步骤确定的过程,重复的多次执行相同的步骤不仅十分枯燥且效率低下。对于这种情况,你可以尝试将过程自动化。对于 linux 管理员而言,这种自动化可以通过 shell 完成。不过目前使用 python 来实现这种自动化操作的方式也方兴未艾。不管使用哪一种方式,我们都能看到自动化处理能够将我们从单调的操作中解放出来,让计算机去自动执行呆板的操作!这也与程序设计的方针不谋而合。

提高撰写文档的效率

工作中我们常常需要撰写一类文档。这些文档的排版格式有明确的规定,内容可根据实际情况进行撰写。在这种情况下我们可以根据文档类别创建统一的模板,将格式与内容分离,消除重复的排版工作。使用统一的模板,你在撰写文档时能够专注于文档的具体内容,不用花额外的精力去按照规定的排版格式修改文档。

自动生成接口描述文档

在写代码的时候,我们常常需要对那些开放给用户使用的 api 进行详细的介绍,说明参数、返回值的意义及函数所实现的功能等等。这样的过程完全可以在写代码的同时完成。

我们可以在写代码时就以预先固定的格式编写注释。可以编写或使用现有的解析工具来解析代码并生成 manual 文档,这样就将生成接口描述文档的过程自动化处理了。我们甚至可以以同一个解析工具来解析注释,然后使用不同的生成工具来生成不同格式的文档。

自动构建项目

一个项目通常由许多部分构成,构建出一个可发布的程序或 sdk 将会有很多的重复性工作。如果能够将这样的过程自动化,那么这其中存在的重复性便可以减少。

老牌的工具要属 gnu make 了,make 工具我也曾经学习过。不过这里我们可以考虑使用 scons 等使用 python 编写的构建系统。使用这些构建系统,我们可以用 python 脚本来作为配置文件配置项目构建的一些具体参数,可以说是相当方便啦!

系统优化

功欲善其事,必先利其器。优化电脑,提高配置,让电脑跑的更快,这当然能够提高效率了!

总结

如何提高工作效率是我想了很久的问题。上面的描述是我的一些思考与具体的实践方法。在我的尝试过程中我无意中看到了《卓有成效的程序员》这本书,得到了不小的启发。在这里我要推荐大家去阅读这本书。同时我也必须说明的是,提高工作效率是一个长期的过程,需要一直去思考与改进!