微信号:fangtalk

介绍:马上入行10年了,为了不想一直贴个程序猿的标签,从码代码、做架构,转向练习码字.我还是一个刚刚开始写字的孩子,认真专注写字的孩子.都说7年可以精通一个行业,IT不敢说精通但也算入行;希望再一个7年以后,我...

Be Professional - 项目规范之道

2015-11-22 20:55 inetfuture

本文是我项目组里的开发组长 inetfuture 整理维护的项目规范,我做了重新整理精简,同时去除了微信公众号不便阅读同时不重要的文字。由于我的微信公众号还不能添加链接,一些推荐链接无法添加,点击底部 阅读原文 查看易收藏的版本,也可以通过原文链接关注 inetfuture(Aaron Wang) 的Github笔记,更欢迎直接提交pull request。


前言


本文是对我自己及团队成员工作上的一些指导或要求,欢迎补充和改进。包括:

  1. 必读的书籍推荐

  2. 开发必备工具

  3. 开发环境配置建议

  4. 做事的原则、方法

  5. 如何编写整洁的代码

  6. 调试技巧

  7. Code review建议

  8. Research 技巧


总结来说就是:Be Professional!


必读书籍资料


  1. 《代码整洁之道》

  2. 《深入理解计算机系统》

  3. 《敏捷软件开发 : 原则、模式与实践》

  4. 《TCP/IP 详解 卷1》

  5. The Art of Command Line

  6. 《深入理解Linux内核》

  7. 《数据结构与算法》


必备工具


VPN


推荐该家:http://gjsq.me/6292696,使用方法:

  • Linux PPTP:https://www.igreenjsq.mobi/shiyong/67.html

  • OS X:https://www.igreenjsq.mobi/mac.html


虚拟主机


每个人都应该配置自己的虚拟主机,便于学习和玩具。推荐这家vultr:http://vps.fangtalk.net


Sublime Text


安装 Package Control:https://packagecontrol.io/installation管理Sublime插件,以下为必备插件:

  • Git

  • GitGutter

  • knockdown

  • SublimeLinter

  • DocBlockr

  • EditorConfig

  • Emmet

  • FileDiffs

  • SublimeCodeIntel


可以将整个配置目录放到 GitHub 上,方便在多台机器上同步(也可以用 Dropbox 同步,参考下面),比如 https://github.com/inetfuture/sublime-config ,配置目录的位置:

  • Linux:~/.config/sublime-text-3/Packages/User

  • OS X:~/Library/Application\ Support/Sublime\ Text\ 3/Packages/User


Dropbox


全客户端支持,包括 Linux ,需要*翻*墙*。国内类似的服务且支持 Linux 的,尝试过金山快盘,可惜同步不稳定,经常出错。


除了同步各种资料外,还可以用来同步一些配置文件,比如各种 dotfiles:~/.bashrc,~/.pep8,~/.gitconfig 等等,把它们放到 Dropbox 的同步目录下,然后建立软链接到本来的位置,这样公司、家里多台机器可以无缝同步,尤其重装系统或者换新机器的时候,各种用习惯了的配置可以快速重新启用。


印象笔记


https://www.yinxiang.com


不建议使用 Evernote 国际版,太卡,而且国内的版本提供的本地化服务更方便。

  • 剪藏浏览器插件:https://appcenter.yinxiang.com/app/evernote-webclipper/web-apps/

  • 关注微信公众号:“我的印象笔记”,可以快速收藏微信内容。


必备的Chrome 插件


  • 直接参考知乎上的精华贴:“有哪些鲜为人知却非常有用的插件”:http://www.zhihu.com/question/23228162 


其它


  • 项目管理和沟通工具Trello: https://trello.com


开发环境配置建议


安装软件原则


  • 优先使用语言版本管理器安装语言运行时,比如 nvm(Node.js),pyenv(Python),rvm(Ruby),jenv(Java),phpbrew(PHP)

    注意,此类工具通常安装在你的 `$HOME` 下,通过修改当前 shell 的 `$PATH` 等环境变量生效,就是说安装或者使用它们的时候,你不需要也不应该使用 `sudo` 。

  • 优先使用语言包管理器安装语言依赖,比如 npm(Node.js),pip(Python),gem(Ruby),maven/gradle(Java),pecl/composer(PHP)

  • 优先使用系统包管理器安装系统依赖,apt-get(Ubuntu),homebrew(OS X)

  • 对于一些第三方工具,优先使用其官方源或者可靠的 PPA 源

  • Ubuntu 必备软件包:`sudo apt-get install -y aptitude gdebi vim curl wget build-essential openssh-server`


做事原则、方法


  • 认真负责,关注细节,追求卓越

    1. 每一份需求都要理解之后再动手,需求不合理的提出来讨论,对产品要有责任心,不仅仅是“按部就班”得做事情。

    2. 提交前仔细测试自己实现的功能,检查代码细节,有交付高质量代码的责任心,而不是依赖其他成员帮你 Reivew 或者 QA 帮你发现 bug 。

    3. 代码仅仅可以工作是不够的,还要可读、易扩展、可维护、安全、高效,等等等等,要用高标准要求自己,写代码要“上心”,不要敷衍、随意。

    4. 细节不一定决定成败但却可以充分体现一个人的工作态度,请认真对待各种流程、规范,比如写英文邮件时,从语法、格式到每一个拼写、标点,再比如 Commit Message 的格式、Coding Style 等等。

  • 主动沟通而不是被动沟通

    1. 对需求、开发规范、代码组织等等各方面存在任何疑问时,主动询问和讨论,不要默不作声、自作主张导致返工和延误。

    2. 自己的代码被别人 Review 时,如果觉得某段代码可能有问题或者不是最优方案,主动提出来讨论,而不是等待审查者询问。前者可以使 Review 更高效,更利于培养同事间的相互信任,后者一是效率低,同时也是一种不负责任的表现。

    3. 进度存在风险时主动知会其他人,而不是默默拖到最后一刻连累大家加班

    4. 做变更时及时通知相关人员,否则可能会浪费队友的时间去排查问题。代码级别的问题可以通过在 GitLab 等代码管理工具上 at 对方。

  • 自我驱动

    1. 自觉深入学习相关技术,而不是用多少学多少,临时抱佛脚。假设你在做 iOS 开发,即便目前所有项目仍在用 Objective-C ,你也应该利用业余时间自觉去学习 Swift ,时刻准备着。

    2. 主动思考产品的走向,自觉进行知识储备、调研。

    3. 自觉重构低质量代码,改善项目流程,等等,保证项目的健康发展。

  • 换位思考

    1. 使用邮件、微信等工具交流时一次性提供必要的上下文,避免低效率的沟通,想一下,我这样描述对方是否可以理解并直接回复。

    2. 无论是做 Code Review 还是提交功能给 QA 测试,尽自己最大努力保证质量,做好自己分内的事,减轻队友的负担。

    3. 作为开发,想一下我该怎样为 leader 分担压力?作为 leader ,想一下我该怎样促进下属工作能力的稳步成长?

  • 从根本上解决问题

    1. 思考问题的原因,不要停留于表面问题的修修补补。


      比如,QA 报了一个 Bug,说在一个输入项中填入 `<script>alert('haha');</script>` ,保存后页面上会弹出提示框,你来修复这个问题的时候要考虑从根本上杜绝脚本注入问题,比如使用 Angular.js 的 `$sanitize` service 过滤输入再显示。相比较而言,不太恰当的做法是仅仅用正则过滤掉输入中的 `<script />` 标签,虽然可以修复这个 Bug,却是治标不治本,如果输入中包含 `onmouseover="alert('haha')"` 这种代码呢?当然这种问题需要你有扎实的基本功,对开发各个方面有较全面的了解,才能一针见血的解决问题。

    2. 每一个问题,想一下有没有办法一劳永逸?或者自动化?

    3. 谁痛苦,谁改变。某件事总是让你很不爽?想办法改变它!

  • 用正确的方式解决问题

    1. 很多问题都有不止一种的解决办法,不要满足于你最初想到的那种,也许有更好的呢?主动去思考目前的方案可维护吗?方便吗?效率高吗?普适吗?

    2. 多看一些最佳实践(Best Practice)的资料,多看一些优秀开源项目的源代码,多了解别人怎么做的你才能及时发现自己的不足。比如 RESTful API,是有一套业界公认的最佳实践的,其本身就是一套约定俗成的东西,如果你没有看过这些最佳实践,随意的设计 URL,随意的使用 HTTP 动词,那你设计出来的 API 其实只是 HTTP API,请不要称其为 RESTful API。再比如你对 Git 不熟,然后不知怎么得把工作目录搞的一团糟,你该怎么办?再 clone 一个重新开始?NO!除非你打算一辈子这么干。你应该去 google 解决方案,并充分认识到自己对 Git 不熟这个事实,然后拿出时间来补充知识。

    3. 不要重复造轮子,尤其是使用第三方库时,也许人家已经提供了现成的解决方案,只是因为你没有仔细看文档,所以不知道。

  • 磨刀不误砍柴工

    1. 学习新知识要尽可能的系统、全面,不要只是为了应付当前工作片面了解。

    2. 使用第三方库、框架时应尽量通读其文档,至少要知道它可以做什么,有哪些限制,遇到具体问题后可以迅速到文档中查看细节。

    3. 常用的技术点要舍得花时间搞清楚其运行原理、内部机制,免的每次出问题都像无头苍蝇,只能瞎猜。比如 Angular.js 的 directive 编译流程是怎样的?Node.js 的异步 IO 是如何运行的?

    4. 工欲善其事,必先利其器。平时要注意效率工具的积累,包括好的代码编辑器、命令行工具、任务管理工具、各种实用小工具等等。对于你常用的编辑器或 IDE 应该花一些时间去熟练它的快捷键,寻找一些好用的插件,毕竟工作每天都要用,投入的精力绝对物超所值。


编写整洁代码


Writing clean code requires the disciplined use of a myriad little techniques applied through a painstakingly acquired sense of "cleanliness". This "code-sense" is the key. Some of us are born with it. Some of us have to fight to acquire it. Not only does it let us see whether code is good or bad, but it also shows us the strategy for applying our discipline to transform bad code into clean code.


基本要求


  • Coding Style,如果有要求,应该严格遵循,任何例外的情况需要讨论决定。

  • 可读性,要容易理解,命名要具有足够描述性,不能有歧义,代码路径、结构要清晰、简洁。

  • 一致性,包括但不限于标识符命名、错误处理、日志格式、文件组织方式、HTTP API 接口设计、UI 交互等各个方面,越是一致的系统越容易上手,越容易维护,反之则维护成本越高。

  • 健壮性,进行必要的输入验证,充分得考虑边界情况,异常处理要周全,防止内存泄露,防止竞态条件,多线程安全,等等。

  • 性能,考虑数据量大或者访问频繁时的情况,对内存、数据库的使用要高效,算法要尽量最优。

    1. 任何涉及数量的地方,在业务场景合理的前提下考虑把数量放大到最大,为最坏的情况做打算。

    2. 数据库:

      1. 操作应尽量批量进行,只查询必需的字段,减少 IO 消耗。

      2. 特别大的查询应在数据库中分页,由程序控制分批次处理,全量取出在内存中计算或者根本不考虑数据量大小是常见的低级错误。合理使用索引,例如尽量使用前缀索引减少索引的数量

  • 安全性,进行必要的权限检查,不能过度信任客户端输入。

  • DRY(Don't Repeat Yourself)原则,复制、粘贴的行为是要坚决禁止的,不知道如何复用代码的要主动与其他成员讨论。

  • 单一职责原则,一个类、文件或者模块不能做的太多,不能做不该它做的事,好的设计是只把一件事做好。

  • 开放、封闭原则,要方便扩展,要考虑到以后的需求。

  • 代码改动方式要合适,不能一味得堆砌代码,需要适时停下来进行重构。

  • 保持干净,不能存在任何无用的文件、代码,所有文档、注释需要同步更新,不能包含注释掉的代码,不能包含临时调试代码,例外情况应该添加注释说明。

  • 所有 Warning 都应该被立即修复,觉得不需要修的,讨论决定后通过修改配置文件禁用掉。


进阶要求


  • 使用多态减少或转移 `if` 判断,https://www.youtube.com/watch?v=4F72VULWFvc&index=1&list=PL693EFD059797C21E


提高代码可读性的技巧


  • 局部变量尽量就近声明。

  • return early, https://www.airpair.com/php/posts/best-practices-for-modern-php-development#4-2-try-not-to-use-else-, http://www.codeproject.com/Articles/626403/How-and-Why-to-Avoid-Excessive-Nesting

  • 在语言本身语法允许的情况下,将主流程放在文件上部,子流程按被调用顺序放在文件下部,这样打开文件后可以比较快的抓住重点,比如:


```coffee

main = ->

doStuff1()

doStuff2()

doStuff3()


doStuff1 = ->

console.log '1'


doStuff2 = ->

console.log '2'


doStuff3 = ->

console.log '3'

```


  • 相关的代码尽量按使用顺序组织在一起,尤其是添加新代码时,不要一味得添加到文件尾部。

  • 布尔变量命名应尽量采用肯定形势。

  • 避免硬编码数字、字符串,应使用常量并给它们有意义的名字。

  • 传递简单数据类型时,适当添加临时变量提高可读性,例如:


```coffee

ignoreError = true

doStuff(ignoreError)

```


如何写注释


  • 代码的意图应该由代码自身来表达,即所谓的可读性,不应该依赖于注释说明,所以优先考虑写更可读的代码。

  • 代码意图明显的情况下,不要加注释重复说明。

  • 以下注释是合理的或者说以下情况需要写注释:

    • 纲要性的注释,简要的描述某一个文件、某一个类或某一个流程。

    • 确实无法从代码本身提高可读性的情况,比如复杂业务逻辑、算法。

    • 代码的作用并不直观时,解释这样做的原因。

    • 存在多种可选方案时,解释为什么选择现在这种。

    • 因为某些限制而使代码不一致、不优雅或存在副作用时,应注明原因及后果。

    • 参考了外部一些资料时,应注明链接,方便其他人查看。

    • 临时标记注释:TODO、FIXME、HACK、OPTIMIZE、REVIEW

  • 注释应随代码更新。


调试技巧


  • 查看日志,比如做 PHP Web 开发要知道 Nginx,PHP-FPM,PHP 的日志文件的位置,必要的时候从中寻找线索。使用 `tail -F file1 file2` 命令可以持续监控多个文件。

  • 通过添加临时 log 语句或断点的形式检查代码路径,很多时候调试是个体力活,并没有什么难度,不要轻易放弃或寻求他人帮助。检查代码是否按预期路径执行了,如果没有,为什么?输入数据的原因吗?或者中间一步数据处理是错的?从数据进入系统开始一步步从前往后分析,用排除法逐步缩小范围,bug 必将无所遁形。另外,有时候代码路径可能牵扯到第三方库,这个时候不要畏惧,代码都是人写的,尤其开源项目通常质量较高,进去看一下,通常没你想象的那么难。

  • 确保读懂日志消息、异常信息、错误输出等,特别是英文内容,不要因为是英文不想读,结果非常明显的线索摆在你面前你却视而不见。比如常见的 git 错误,都会有相应的描述甚至建议的解决办法。再比如做 Web 开发,一个页面打不开,最起码你要先看一下 HTTP Response 是什么,状态码,body 等。如果实在看不懂,google 之。

  • 有意识的组织整理常见错误,依据过往经验快速定位问题。例如 PHP 开发时碰到 HTTP 404,基本可以排除代码逻辑问题,应该检查拼写错误、Nginx 配置、MVC 框架路由配置、文件路径等。

  • 使用第三方组件时,遇到问题要知道去查看它的 issue 列表,也许别人也遇到了同样的问题并且已经报了 Bug ,尤其是 GitHub 上的开源项目。


Code Review


目的


  • 提高代码质量,查漏补缺。

  • 相互学习。

  • 促进项目内知识流动,防止对某个个人过分依赖。


Commit Message 规范


规定格式如下:

```

$(scope): $(subject)


$(description)

```


  • `$(scope)`:必需,取决于具体项目,一般为一组固定值,用来描述本次 commit 影响的范围,比如 https://github.com/nodejs/node/commits/master ,后加入项目的新成员应遵循已有的 scope 约定。

  • `$(subject)`:必需,50 个字符左右的简要说明,首字母小写,通常是动宾结构,描述做了什么事情,动词用一般现在时,禁止出现 *update code* , *fix bug* 等无实际意义的描述,好的例子: *select connector by sorting free memory* (不需要形如 *update about how to select connector ...* 的啰嗦写法), *fix sucess tip can not show on IE8* (不需要形如 *fix bug of ...* 的啰嗦写法)。

  • `$(description)`:可选,详细说明,建议使用列表罗列要点。


流程


  • 提交者发起 topic 分支到目标分支的 Merge Request 。

    • 代码变动要尽量小且专注于一个任务,不要攒的很大,或者做多个任务,要保证审查者可以较快、较容易的 Review 。

    • 交给别人之前一定要自己先 Review 一遍,别人只是帮你查漏补缺,对自己的代码负责,不要浪费别人的时间。

    • 发起后,要在 GitLab 或者其它 Review 工具上 double check 变更集。

  • 审查者 Review 代码。

    • 对 [编写整洁的代码](#编写整洁代码) 中各项要求进行检查

    • 在任何有疑问或建议的地方留 comment。

    • 从中学习一些好的东西。

    • 完成后,如果有问题需要修复,留 comment “Reviewed and waiting for fix”,否则进行第 4 步。

  • 提交者响应 comments 。

    • 确实有问题的,修复之。如果该分支未被其他人使用,应使用 `git commit --amend` 提交以减少不必要的 commit 历史。

    • 不同意的,讨论。

    • 完成后,留 comment “Fixed”,审查者再次检查,回到第二步。

  • 审查者确认没有问题之后,将 Merge Request 转发给目标分支的维护者进行合并。


Research 技巧


工作中难免需要学习新技术,这个过程中也有一些技巧可以实践。


  • 使用 Google 搜索,除非是特定于国内的东西,比如微信开发相关,不要使用百度。

百度搜索质量偏低是事实,一方面是受限于百度自身的技术,另一方面是因为中文搜索有很多垃圾站,以及低质量的转载博客。经常出现前几页都是各种垃圾站在重复同一篇文章,而且广告满天飞,排版稀烂。还有新浪、网易的博客,很多都是复制粘贴的转载,格式一团糟,原文却不知所踪。更不要提很多技术中文资料相对较少,更新不及时,翻译质量不高等等问题。


养成使用在 Google 上使用英文关键词搜索的好习惯绝对可以节省你的大量时间和精力。


  • 搜索时要注意时效性

取决于具体的技术,搜索出来的东西很多可能已经过时了,要注意区分,不要被过时的东西误导。快速浏览搜索结果时捎带看一下时间也是一个好习惯,有多条相似结果时当然是最新的会靠谱一点。


  • 掌握使用搜索引擎的一些小技巧,http://www.lifehack.org/articles/technology/20-tips-use-google-search-efficiently.html

  • 注意搜集、整理一些高质量的网站、博客

当你研究一个新东西的时候肯定会进行很多搜索,其中有些结果可能质量很高,这时可以快速浏览一下这个网站或者博客的首页,看看是否有收藏价值,或者有没有其它相关文章值得看一下。


  • 阅读权威、系统的书籍

通过使用搜索引擎或者阅读博客等通常可以对某种技术有个大概了解,或者可以解决某个具体问题,但是对于较复杂的技术,系统学习是必不可少的,看书往往是最有效的方式。可以到豆瓣阅读或者各大电商网站上通过评分排名来筛选好的书籍。如果是国外书籍,尽量选择英文原版,一开始会比较吃力,熟悉了就好了。


跟筛选搜索结果一样,尽量选择较新的书籍。


  • 持续关注

每个人理解新事物都有一个从浅入深的过程,新学的技术最好可以不断夯实,反复咀嚼,不要停留在表面。可以通过订阅一些邮件列表、知名博客来不断补充知识盲点,学习最佳实践,反思自己的不足,以及了解技术的最新动态。


 
大房说 更多文章 年过三十,开始码字 获取知识的渠道 最近读的几本好书 开通了知乎专栏 我所亲见的前端技术变革
猜您喜欢 MySQL for update 死锁案例 测试向开发行进,论自动化测试 分享 | 阿里全息大数据构建与应用(PPT版)。 平安金融科技移动技术周报(第十期) 不比不知道!女排工资到底有多低?(附中国女排妹子生活照,美得不敢认)