From c8767dde046a9ea9a519a600aacfccbce46a65ad Mon Sep 17 00:00:00 2001 From: Phodal HUANG Date: Mon, 7 Oct 2019 09:07:46 +0800 Subject: [PATCH] chore: update build --- github-roam.md | 899 ++++++++-------- index.html | 2671 ++++++++++++++++++++++++------------------------ 2 files changed, 1791 insertions(+), 1779 deletions(-) diff --git a/github-roam.md b/github-roam.md index d7aff5a..d56939c 100644 --- a/github-roam.md +++ b/github-roam.md @@ -7,9 +7,9 @@ 黄峰达(Phodal Huang)是一个创客、工程师、咨询师和作家。他毕业于西安文理学院电子信息工程专业,现作为一个咨询师就职于 ThoughtWorks 深圳。长期活跃于开源软件社区 GitHub,目前专注于物联网和前端领域。 -作为一个开源软件作者,著有 Growth、Stepping、Lan、Echoesworks 等软件。其中开源学习应用 Growth,广受读者和用户好评,可在 APP Store 及各大 Android 应用商店下载。 +作为一个开源软件作者,著有 Growth、Stepping、Lan、Echoesworks 等软件。其中开源学习应用 Growth,广受读者和用户好评,可在 App Store 及各大 Android 应用商店下载。 -作为一个技术作者,著有《自己动手设计物联网》(电子工业出版社)、《全栈应用开发:精益实践》(电子工业出版社,正在出版)。并在 GitHub 上开源有《Growth: 全栈增长工程师指南》、《GitHub 漫游指南》等七本电子书。 +作为一个技术作者,著有《自己动手设计物联网》(电子工业出版社)、《全栈应用开发:精益实践》(电子工业出版社,正在出版)。并在 GitHub 上开源有《Growth:全栈增长工程师指南》、《GitHub 漫游指南》等七本电子书。 作为技术专家,他为英国 Packt 出版社审阅有物联网书籍《Learning IoT》、《Smart IoT》,前端书籍《Angular 2 Serices》、《Getting started with Angular》等技术书籍。 @@ -18,30 +18,30 @@ 其它相关信息: - 微博:[http://weibo.com/phodal](http://weibo.com/phodal) - - GitHub: [https://github.com/phodal](https://github.com/phodal) + - GitHub:[https://github.com/phodal](https://github.com/phodal) - 知乎:[https://www.zhihu.com/people/phodal](https://www.zhihu.com/people/phodal) - SegmentFault:[https://segmentfault.com/u/phodal](https://segmentfault.com/u/phodal) -当前为预览版,在使用的过程中遇到任何问题请及时与我联系。阅读过程中的问题,不妨在GitHub上提出来: [Issues](https://github.com/phodal/github/issues) +当前为预览版,在使用的过程中遇到任何问题请及时与我联系。阅读过程中的问题,不妨在 GitHub 上提出来:[Issues](https://github.com/phodal/github/issues) -阅读过程中遇到语法错误、拼写错误、技术错误等等,不妨来个Pull Request,这样可以帮助到其他阅读这本电子书的童鞋。 +阅读过程中遇到语法错误、拼写错误、技术错误等等,不妨来个 Pull Request,这样可以帮助到其他阅读这本电子书的童鞋。 我的电子书: * 《[GitHub 漫游指南](https://github.com/phodal/github-roam)》 * 《[我的职业是前端工程师](https://github.com/phodal/fe)》 * 《[Serverless 架构应用开发指南](https://github.com/phodal/serverless)》 - * 《[Growth: 全栈增长工程师指南](https://github.com/phodal/growth-ebook)》 - * 《[Phodal's Idea实战指南](https://github.com/phodal/ideabook)》 + * 《[Growth:全栈增长工程师指南](https://github.com/phodal/growth-ebook)》 + * 《[Phodal's Idea 实战指南](https://github.com/phodal/ideabook)》 * 《[一步步搭建物联网系统](https://github.com/phodal/designiot)》 * 《[RePractise](https://github.com/phodal/repractise)》 - * 《[Growth: 全栈增长工程师实战](https://github.com/phodal/growth-in-action)》 + * 《[Growth:全栈增长工程师实战](https://github.com/phodal/growth-in-action)》 -我的微信公众号: +我的微信公众号: ![作者微信公众号:phodal-weixin](./img/wechat.jpg) -支持作者,可以加入作者的小密圈: +支持作者,可以加入作者的小密圈: ![小密圈](./img/xiaomiquan.jpg) @@ -49,45 +49,45 @@ ![支付宝](./img/alipay.png) ![微信](./img/wechat-pay.png) -我的GitHub主页上写着加入的时间——``Joined on Nov 8, 2010``,那时才大一,在那之后的那么长的日子里我都没有登录过。也许是因为我学的不是计算机,到了今天——``2015.3.9``,我才发现这其实是程序员的社交网站。 +我的 GitHub 主页上写着加入的时间——``Joined on Nov 8, 2010``,那时才大一,在那之后的那么长的日子里我都没有登录过。也许是因为我学的不是计算机,到了今天——``2015.3.9``,我才发现这其实是程序员的社交网站。 -过去,曾经有很长的一些时间我试过在GitHub上连击,也试着去了解别人是如何用好这个工具的。当然粉丝在GitHub上也是很重要的。 +过去,曾经有很长的一些时间我试过在 GitHub 上连击,也试着去了解别人是如何用好这个工具的。当然粉丝在 GitHub 上也是很重要的。 -在这里,我会试着将我在GitHub上学到的东西一一分享出来。 +在这里,我会试着将我在 GitHub 上学到的东西一一分享出来。 -## 我与GitHub的故事 +## 我与 GitHub 的故事 -在我大四找工作的时候,试图去寻找一份硬件、物联网相关的工作(ps: 专业是电子信息工程)。尽管简历上写得满满的各种经历、经验,然而并没有卵用。跑了几场校园招聘会后,十份简历(ps: 事先已经有心里准备)一个也没有投出去——因为学校直接被拒。我对霸面什么的一点兴趣都没有,千里马需要伯乐。后来,我加入了[Martin Flower](https://martinfowler.com/)所在的公司,当然这是后话了。 +在我大四找工作的时候,试图去寻找一份硬件、物联网相关的工作(PS:专业是电子信息工程)。尽管简历上写得满满的各种经历、经验,然而并没有卵用。跑了几场校园招聘会后,十份简历(PS:事先已经有心里准备)一个也没有投出去——因为学校直接被拒。我对霸面什么的一点兴趣都没有,千里马需要伯乐。后来,我加入了[Martin Flower](https://martinfowler.com/)所在的公司,当然这是后话了。 -这是一个残酷的世界,在学生时代,如果你长得不帅不高的话,那么多数的附加技能都是白搭(ps: 通常富的是看不到这篇文章的)。在工作时期,如果你上家没有名气,那么将会影响你下一份工作的待遇。而,很多东西却可以改变这些,GitHub就是其中一个。 +这是一个残酷的世界,在学生时代,如果你长得不帅不高的话,那么多数的附加技能都是白搭(PS:通常富的是看不到这篇文章的)。在工作时期,如果你上家没有名气,那么将会影响你下一份工作的待遇。而,很多东西却可以改变这些,GitHub 就是其中一个。 -注册GitHub的时候大概是大一的时候,我熟悉的时候已经是大四了,现在已经毕业一年了。在过去的近两年里,我试着以几个维度在GitHub上创建项目: +注册 GitHub 的时候大概是大一的时候,我熟悉的时候已经是大四了,现在已经毕业一年了。在过去的近两年里,我试着以几个维度在 GitHub 上创建项目: -1. 快速上手框架来实战,即demo +1. 快速上手框架来实战,即 demo 2. 重构别人的代码 3. 创建自己可用的框架 4. 快速构建大型应用 5. 构建通用的框架 -### GitHub与收获 +### GitHub 与收获 -先说说**与技能无关的收获**吧,毕业设计做的是一个《[最小物联网系统](https://github.com/phodal/iot)》,考虑到我们专业老师没有这方面知识,答辩时会带来问题,尽量往这方面靠拢。当我毕业后,这个项目已经有过百个star了,这样易上手的东西还是比较受欢迎的(ps: 不过这种硬件相关的项目通常受限于GitHub上硬件开发工程师比较少的困扰)。 +先说说**与技能无关的收获**吧,毕业设计做的是一个《[最小物联网系统](https://github.com/phodal/iot)》,考虑到我们专业老师没有这方面知识,答辩时会带来问题,尽量往这方面靠拢。当我毕业后,这个项目已经有过百个 Star 了,这样易上手的东西还是比较受欢迎的(PS:不过这种硬件相关的项目通常受限于GitHub上硬件开发工程师比较少的困扰)。 -毕业后一个月收到PACKT出版社的邮件(ps: 他们是在github上找到我的),内容是关于Review一本[物联网](iot)书籍,即在《[从Review到翻译IT书籍](http://www.phodal.com/blog/review-it-books-with-translate-book/)》中提到的《Learning Internet of Things》。作为一个四级没过的"物联网专家",去审阅一本英文的物联网书籍。。。 +毕业后一个月收到 PACKT 出版社的邮件(PS:他们是在 GitHub 上找到我的),内容是关于 Review 一本[物联网](iot)书籍,即在《[从 Review 到翻译 IT书籍](http://www.phodal.com/blog/review-it-books-with-translate-book/)》中提到的《Learning Internet of Things》。作为一个四级没过的"物联网专家",去审阅一本英文的物联网书籍。。。 当然,后来是审阅完了,书上有我的英文简介。 ![Phodal Huang Introduction](./img/phodal-intro.jpg) -一个月前,收到MANNING出版社的邮件(ps: 也是在github上),关于Review一本[物联网](iot)书籍的目录,并提出建议。 +一个月前,收到 MANNING 出版社的邮件(PS:也是在 GitHub 上),关于 Review 一本[物联网](iot)书籍的目录,并提出建议。 也因此带来了其他更多的东西,当然不是这里的主题。在这里,我们就不讨论各种骚扰邮件,或者中文合作。从没有想象过,我也可以在英语世界有一片小天地。 -这些告诉我们,GitHub上找一个你擅长的主题,那么会有很多人找上你的。 +这些告诉我们,GitHub 上找一个你擅长的主题,那么会有很多人找上你的。 -### GitHub与成长 +### GitHub 与成长 -过去写过一篇《[如何通过github提升自己](http://www.phodal.com/blog/use-github-grow-self/)》的文章,现在只想说三点: +过去写过一篇《[如何通过 GitHub 提升自己](http://www.phodal.com/blog/use-github-grow-self/)》的文章,现在只想说三点: 1. 测试 2. 更多的测试 @@ -97,31 +97,31 @@ 如果你的项目代码有上千行,如果你能保证测试覆盖率可以达到95%以的话,那么我想你的项目不会有太复杂的函数。假使有这样的函数,那么它也是被测试覆盖住的。 -如果你在用心做这个项目,那么你看到代码写得不好也会试着改进,即重构。当有了一些,你的技能会不断提升。你开始会试着接触更多的东西,如stub,如mock,如fakeserver。 +如果你在用心做这个项目,那么你看到代码写得不好也会试着改进,即重构。当有了一些,你的技能会不断提升。你开始会试着接触更多的东西,如 stub,如 mock,如 fakeserver。 有一天,你会发现你离不开测试。 -然后就会相信: **那些没有写测试的项目都是在耍流氓** +然后就会相信:**那些没有写测试的项目都是在耍流氓** -## 为什么你应该深入GitHub +## 为什么你应该深入 GitHub 上面我们说的都是我们可以收获到的东西,我们开始尝试就意味着我们知道它可能给我们带来好处。上面已经提到很多可以提升自己的例子了,这里再说说其他的。 ### 方便工作 -我们可以从中获取到不同的知识、内容、信息。每个人都可以从别人的代码中学习,当我们需要构建一个库的时候,我们可以在上面寻找不同的库和代码来实现我们的功能。如当我在实现一个库的时候,我会在GitHub上找到相应的组件: +我们可以从中获取到不同的知识、内容、信息。每个人都可以从别人的代码中学习,当我们需要构建一个库的时候,我们可以在上面寻找不同的库和代码来实现我们的功能。如当我在实现一个库的时候,我会在 GitHub 上找到相应的组件: - Promise 支持 -- Class类(ps:没有一个好的类使用的方式) +- Class 类(PS:没有一个好的类使用的方式) - Template 一个简单的模板引擎 - Router 用来控制页面的路由 -- Ajax 基本的Ajax Get/Post请求 +- Ajax 基本的 Ajax Get/Post 请求 ### 获得一份工作 -越来越多的人因为GitHub获得工作,因为他们的做的东西正好符合一些公司的要求。那么,这些公司在寻找代码的时候,就会试着邀请他们。 +越来越多的人因为 GitHub 获得工作,因为他们的做的东西正好符合一些公司的要求。那么,这些公司在寻找代码的时候,就会试着邀请他们。 -因而,在GitHub寻找合适的候选人,已经是一种趋势。 +因而,在 GitHub 寻找合适的候选人,已经是一种趋势。 ### 扩大交际 @@ -143,7 +143,7 @@ 因此,我就长话短说,一般就是取一个有意义的名字,当然没有意义也没有任何问题。 -通常而言,如果自己计划有一系列的开源项目,那么我们可以保持一定的命令规则。 +通常而言,如果自己计划有一系列的开源项目,那么我们可以保持一定的命名规则。 挑选好 LICENSE --- @@ -213,43 +213,43 @@ 如果你不介意的话,你可以使用公有领域(Public Domain)。可是这样一来,万一有一天,别人直接拿你的作品出书,你就骂爹了。 -# Git基本知识与GitHub使用 +# Git 基本知识与 GitHub 使用 ## Git -从一般开发者的角度来看,git有以下功能: +从一般开发者的角度来看,Git 有以下功能: 1. 从服务器上克隆数据库(包括代码和版本信息)到单机上。 2. 在自己的机器上创建分支,修改代码。 3. 在单机上自己创建的分支上提交代码。 4. 在单机上合并分支。 -5. 新建一个分支,把服务器上最新版的代码fetch下来,然后跟自己的主分支合并。 +5. 新建一个分支,把服务器上最新版的代码 fetch 下来,然后跟自己的主分支合并。 6. 生成补丁(patch),把补丁发送给主开发者。 7. 看主开发者的反馈,如果主开发者发现两个一般开发者之间有冲突(他们之间可以合作解决的冲突),就会要求他们先解决冲突,然后再由其中一个人提交。如果主开发者可以自己解决,或者没有冲突,就通过。 -8. 一般开发者之间解决冲突的方法,开发者之间可以使用pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。 +8. 一般开发者之间解决冲突的方法,开发者之间可以使用 pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。 -从主开发者的角度(假设主开发者不用开发代码)看,git有以下功能: +从主开发者的角度(假设主开发者不用开发代码)看,Git 有以下功能: 1. 查看邮件或者通过其它方式查看一般开发者的提交状态。 2. 打上补丁,解决冲突(可以自己解决,也可以要求开发者之间解决以后再重新提交,如果是开源项目,还要决定哪些补丁有用,哪些不用)。 3. 向公共服务器提交结果,然后通知所有开发人员。 -### Git初入 +### Git 初入 -如果是第一次使用Git,你需要设置署名和邮箱: +如果是第一次使用 Git,你需要设置署名和邮箱: ``` $ git config --global user.name "用户名" $ git config --global user.email "电子邮箱" ``` -将代码仓库clone到本地,其实就是将代码复制到你的机器里,并交由Git来管理: +将代码仓库 clone 到本地,其实就是将代码复制到你的机器里,并交由 Git 来管理: ``` $ git clone git@github.com:someone/symfony-docs-chs.git ``` -你可以修改复制到本地的代码了(symfony-docs-chs项目里都是rst格式的文档)。当你觉得完成了一定的工作量,想做个阶段性的提交: +你可以修改复制到本地的代码了(symfony-docs-chs 项目里都是 rst 格式的文档)。当你觉得完成了一定的工作量,想做个阶段性的提交: 向这个本地的代码仓库添加当前目录的所有改动: @@ -277,22 +277,22 @@ $git status ![After add](./img/after-add.png) -可以看到状态的变化是从黄色到绿色,即unstage到add。 +可以看到状态的变化是从黄色到绿色,即 unstage 到 add。 ## GitHub -Wiki百科上是这么说的 +Wiki 百科上是这么说的 > GitHub 是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目。它由GitHub公司(曾称Logical Awesome)的开发者Chris Wanstrath、PJ Hyett和Tom Preston-Werner 使用Ruby on Rails编写而成。 -当然让我们看看官方的介绍: +当然让我们看看官方的介绍: > GitHub is the best place to share code with friends, co-workers, classmates, and complete strangers. Over eight million people use GitHub to build amazing things together. -它还是什么? +它还是什么? - 网站 - 免费博客 @@ -303,11 +303,11 @@ Wiki百科上是这么说的 - 托管编程环境 - 写作 -等等。看上去像是大餐,但是你还需要了解点什么? +等等。看上去像是大餐,但是你还需要了解点什么? ### 版本管理与软件部署 -jQuery[^jQuery]在发布版本``2.1.3``,一共有152个commit。我们可以看到如下的提交信息: +jQuery[^jQuery] 在发布版本``2.1.3``,一共有 152 个 commit。我们可以看到如下的提交信息: - Ajax: Always use script injection in globalEval … bbdfbb4 - Effects: Reintroduce use of requestAnimationFrame … 72119e0 @@ -316,7 +316,7 @@ jQuery[^jQuery]在发布版本``2.1.3``,一共有152个commit。我们可以 - Build: Update commitplease dev dependency - ... -### GitHub与Git +### GitHub 与 Git > Git是一个分布式的版本控制系统,最初由Linus Torvalds编写,用作Linux内核代码的管理。在推出后,Git在其它项目中也取得了很大成功,尤其是在Ruby社区中。目前,包括Rubinius、Merb和Bitcoin在内的很多知名项目都使用了Git。Git同样可以被诸如Capistrano和Vlad the Deployer这样的部署工具所使用。 @@ -324,15 +324,15 @@ jQuery[^jQuery]在发布版本``2.1.3``,一共有152个commit。我们可以 ### 在 GitHub 创建项目 -接着,我们试试在上面创建一个项目: +接着,我们试试在上面创建一个项目: ![GitHub Roam](./img/github-roam-create.jpg) -就会有下面的提醒: +就会有下面的提醒: ![GitHub Roam](./img/project-init.jpg) -它提供多种方式的创建方法: +它提供多种方式的创建方法: > …or create a new repository on the command line @@ -356,7 +356,7 @@ git push -u origin master ## GitHub 流行项目分析 -之前曾经分析过一些GitHub的用户行为,现在我们先来说说GitHub上的Star吧。(截止: 2015年3月9日23时。) +之前曾经分析过一些 GitHub 的用户行为,现在我们先来说说 GitHub 上的 Star 吧。(截止:2015年3月9日23时。) 用户 | 项目名 | Language | Star | Url -----|---------- |----------|------|---- @@ -366,7 +366,7 @@ angular | angular.js | JavaScript | 36,061 | [https://github.com/angular/angular mbostock | d3 | JavaScript | 35,257 | [https://github.com/mbostock/d3](https://github.com/mbostock/d3) joyent | node | JavaScript | 35,077 | [https://github.com/joyent/node](https://github.com/joyent/node) -上面列出来的是前5的,看看大于1万个stars的项目的分布,一共有82个: +上面列出来的是前5的,看看大于 1 万个 Stars 的项目的分布,一共有 82 个: 语言 | 项目数 -----|----- @@ -381,24 +381,24 @@ Shell | 2 Go | 2 C | 2 -类型分布: +类型分布: - - 库和框架: 如``jQuery`` - - 系统: 如``Linux``、``hhvm``、``docker`` - - 配置集: 如``dotfiles`` - - 辅助工具: 如``oh-my-zsh`` - - 工具: 如``Homewbrew``和``Bower`` - - 资料收集: 如``free programming books``,``You-Dont-Know-JS``,``Font-Awesome`` - - 其他:简历如``Resume`` + - 库和框架:如``jQuery`` + - 系统:如``Linux``、``hhvm``、``docker`` + - 配置集:如``dotfiles`` + - 辅助工具:如``oh-my-zsh`` + - 工具:如``Homewbrew``和``Bower`` + - 资料收集:如``free programming books``,``You-Dont-Know-JS``,``Font-Awesome`` + - 其他:简历如``Resume`` ## Pull Request -除了创建项目之外,我们也可以创建Pull Request来做贡献。 +除了创建项目之外,我们也可以创建 Pull Request 来做贡献。 -### 我的第一个PR +### 我的第一个 PR -我的第一个PR是给一个小的Node的CoAP相关的库的Pull Request。原因比较简单,是因为它的README.md写错了,导致我无法进行下一步。 +我的第一个 PR 是给一个小的 Node 的 CoAP 相关的库的 Pull Request。原因比较简单,是因为它的 README.md 写错了,导致我无法进行下一步。 const dgram = require('dgram') - , coapPacket = require('coap-packet') @@ -419,42 +419,42 @@ C | 2 ### CLA -CLA即Contributor License Agreement,在为一些大的组织、机构提交Pull Request的时候,可能需要签署这个协议。他们会在你的Pull Request里问你,只有你到他们的网站去注册并同意协议才会接受你的PR。 +CLA 即 Contributor License Agreement,在为一些大的组织、机构提交 Pull Request 的时候,可能需要签署这个协议。他们会在你的 Pull Request 里问你,只有你到他们的网站去注册并同意协议才会接受你的 PR。 -以下是我为Google提交的一个PR +以下是我为 Google 提交的一个 PR ![Google CLA](./img/google-cla.png) -以及Eclipse的一个PR +以及 Eclipse 的一个 PR ![Eclipse CLA](./img/eclipse-cla.png) -他们都要求我签署CLA。 +他们都要求我签署 CLA。 # 构建 GitHub 项目 ## 如何用好 GitHub -如何用好 GitHub,并实践一些敏捷软件开发是一个很有意思的事情.我们可以在上面做很多事情,从测试到CI,再到自动部署. +如何用好 GitHub,并实践一些敏捷软件开发是一个很有意思的事情.我们可以在上面做很多事情,从测试到 CI,再到自动部署. ### 敏捷软件开发 -显然我是在扯淡,这和敏捷软件开发没有什么关系。不过我也不知道瀑布流是怎样的。说说我所知道的一个项目的组成吧: +显然我是在扯淡,这和敏捷软件开发没有什么关系。不过我也不知道瀑布流是怎样的。说说我所知道的一个项目的组成吧: - - 看板式管理应用程序(如trello,简单地说就是管理软件功能) - - CI(持续集成) + - 看板式管理应用程序(如 trello,简单地说就是管理软件功能) + - CI(持续集成) - 测试覆盖率 - - 代码质量(code smell) + - 代码质量(code smell) -对于一个不是远程的团队(如只有一个人的项目) 来说,Trello、Jenkin、Jira不是必需的: +对于一个不是远程的团队(如只有一个人的项目)来说,Trello、Jenkin、Jira不是必需的: > 你存在,我深深的脑海里 -当只有一个人的时候,你只需要明确知道自己想要什么就够了。我们还需要的是CI、测试,以来提升代码的质量。 +当只有一个人的时候,你只需要明确知道自己想要什么就够了。我们还需要的是 CI、测试,以来提升代码的质量。 ### 测试 -通常我们都会找Document,如果没有的话,你会找什么?看源代码,还是看测试? +通常我们都会找 Document,如果没有的话,你会找什么?看源代码,还是看测试? ```javascript it("specifying response when you need it", function (done) { @@ -476,17 +476,17 @@ it("specifying response when you need it", function (done) { }); ``` -代码来源: [https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) +代码来源:[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) 上面的测试用例,清清楚楚地写明了用法,虽然写得有点扯。 -等等,测试是用来干什么的。那么,先说说我为什么会想去写测试吧: +等等,测试是用来干什么的。那么,先说说我为什么会想去写测试吧: - - 我不希望每次做完一个个新功能的时候,再手动地去测试一个个功能。(自动化测试) + - 我不希望每次做完一个个新功能的时候,再手动地去测试一个个功能。(自动化测试) - 我不希望在重构的时候发现破坏了原来的功能,而我还一无所知。 - 我不敢push代码,因为我没有把握。 -虽然,我不是TDD的死忠,测试的目的是保证功能正常,TDD没法让我们写出质量更高的代码。但是有时TDD是不错的,可以让我们写出逻辑更简单地代码。 +虽然,我不是 TDD 的死忠,测试的目的是保证功能正常,TDD 没法让我们写出质量更高的代码。但是有时TDD是不错的,可以让我们写出逻辑更简单地代码。 也许你已经知道了``Selenium``、``Jasmine``、``Cucumber``等等的框架,看到过类似于下面的测试 @@ -504,7 +504,7 @@ it("specifying response when you need it", function (done) { ✓ should be able fadeout elements ``` -代码来源: [https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) +代码来源:[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) 看上去似乎每个测试都很小,不过补完每一个测试之后我们就得到了测试覆盖率 @@ -516,7 +516,7 @@ lettuce.js | 98.58% (209 / 212)| 82.98%(78 / 94) | 100.00% (54 / 54) | 98.58% (2 ### CI -虽然node.js不算是一门语言,但是因为我们用的node,下面的是一个简单的``.travis.yml``示例: +虽然 node.js 不算是一门语言,但是因为我们用的 node,下面的是一个简单的 ``.travis.yml`` 示例: ```yml language: node_js @@ -531,23 +531,23 @@ install: npm install after_success: CODECLIMATE_REPO_TOKEN=321480822fc37deb0de70a11931b4cb6a2a3cc411680e8f4569936ac8ffbb0ab codeclimate < coverage/lcov.info ``` -代码来源: [https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) +代码来源:[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) -我们把这些集成到``README.md``之后,就有了之前那张图。 +我们把这些集成到 ``README.md`` 之后,就有了之前那张图。 CI对于一个开发者在不同城市开发同一项目上来说是很重要的,这意味着当你添加的部分功能有测试覆盖的时候,项目代码会更加强壮。 ### 代码质量 -像``jslint``这类的工具,只能保证代码在语法上是正确的,但是不能保证你写了一堆bad smell的代码。 +像 ``jslint`` 这类的工具,只能保证代码在语法上是正确的,但是不能保证你写了一堆 bad smell 的代码。 - 重复代码 - 过长的函数 - 等等 -``Code Climate``是一个与github集成的工具,我们不仅仅可以看到测试覆盖率,还有代码质量。 +``Code Climate`` 是一个与 GitHub 集成的工具,我们不仅仅可以看到测试覆盖率,还有代码质量。 -先看看上面的ajax类: +先看看上面的 ajax 类: ```javascript Lettuce.get = function (url, callback) { @@ -574,9 +574,9 @@ Lettuce.send = function (url, method, callback, data) { }; ``` -代码来源: [https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) +代码来源:[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce) -在[Code Climate](https://codeclimate.com/github/phodal/lettuce/src/ajax.js)在出现了一堆问题 +在 [Code Climate](https://codeclimate.com/github/phodal/lettuce/src/ajax.js) 在出现了一堆问题 - Missing "use strict" statement. (Line 2) - Missing "use strict" statement. (Line 14) @@ -592,19 +592,19 @@ Lettuce.send = function (url, method, callback, data) { 在之前说到 -> 奋斗了近半个月后,将fork的代码读懂、重构、升级版本、调整,添加新功能、添加测试、添加CI、添加分享之后,终于almost finish。 +> 奋斗了近半个月后,将 fork 的代码读懂、重构、升级版本、调整,添加新功能、添加测试、添加 CI、添加分享之后,终于 almost finish。 今天就来说说是怎样做的。 -以之前造的[Lettuce](https://github.com/phodal/lettuce)为例,里面有: +以之前造的 [Lettuce](https://github.com/phodal/lettuce) 为例,里面有: - - 代码质量(Code Climate) - - CI状态(Travis CI) - - 测试覆盖率(96%) - - 自动化测试(npm test) + - 代码质量(Code Climate) + - CI状态(Travis CI) + - 测试覆盖率(96%) + - 自动化测试(npm test) - 文档 -按照[Web Developer路线图](https://github.com/phodal/awesome-developer)来说,我们还需要有: +按照 [Web Developer 路线图](https://github.com/phodal/awesome-developer)来说,我们还需要有: - 版本管理 - 自动部署 @@ -613,26 +613,26 @@ Lettuce.send = function (url, method, callback, data) { ### 代码模块化 -在SkillTree的源码里,大致分为三部分: +在 SkillTree 的源码里,大致分为三部分: - - namespace函数: 顾名思义 - - Calculator也就是TalentTree,主要负责解析、生成url,头像,依赖等等 - - Skill 主要是tips部分。 + - namespace 函数:顾名思义 + - Calculator 也就是 TalentTree,主要负责解析、生成 url,头像,依赖等等 + - Skill 主要是 tips 部分。 -而这一些都在一个js里,对于一个库来说,是一件好事,但是对于一个项目来说,并非如此。 +而这一些都在一个 JS 里,对于一个库来说,是一件好事,但是对于一个项目来说,并非如此。 依赖的库有 - jQuery - Knockout -好在Knockout可以用Require.js进行管理,于是,使用了``Require.js``进行管理: +好在 Knockout 可以用 Require.js 进行管理,于是,使用了 ``Require.js`` 进行管理: ```html ``` -``main.js``配置如下: +``main.js`` 配置如下: ```javascript require.config({ @@ -653,7 +653,7 @@ require(['lib/knockout', 'scripts/TalentTree', 'json!data/web.json'], function(k }); ``` -text、json插件主要是用于处理web.json,即用json来处理技能,于是不同的类到了不同的js文件。 +text、JSON 插件主要是用于处理 web.json,即用 JSON 来处理技能,于是不同的类到了不同的 JS 文件。 . |____Book.js @@ -665,7 +665,7 @@ text、json插件主要是用于处理web.json,即用json来处理技能,于 |____TalentTree.js |____Utils.js -加上了后来的推荐阅读书籍等等。而Book和Link都是继承自Doc。 +加上了后来的推荐阅读书籍等等。而 Book 和 Link 都是继承自 Doc。 ```javascript define(['scripts/Doc'], function(Doc) { @@ -679,7 +679,7 @@ define(['scripts/Doc'], function(Doc) { }); ``` -而这里便是后面对其进行重构的内容。Doc类则是Skillock中类的一个缩影 +而这里便是后面对其进行重构的内容。Doc 类则是 Skillock 中类的一个缩影 ```javascript define([], function() { @@ -696,7 +696,7 @@ define([], function() { }); ``` -或者说这是一个AMD的Class应该有的样子。考虑到this的隐性绑定,作者用了self=this来避免这个问题。最后Return了这个对象,我们在调用的就需要new一个。大部分在代码中返回的都是对象,除了在Utils类里面返回的是函数: +或者说这是一个 AMD 的 Class 应该有的样子。考虑到 this 的隐性绑定,作者用了self=this 来避免这个问题。最后 Return 了这个对象,我们在调用的就需要 new 一个。大部分在代码中返回的都是对象,除了在 Utils 类里面返回的是函数: ```javascript return { @@ -710,7 +710,7 @@ return { ### 自动化测试 -一直习惯用Travis CI,于是也继续用Travis Ci,``.travis.yml``配置如下所示: +一直习惯用 Travis CI,于是也继续用 Travis Ci,``.travis.yml`` 配置如下所示: ```yml language: node_js @@ -725,9 +725,9 @@ branches: - gh-pages ``` -使用gh-pages的原因是,我们一push代码的时候,就可以自动测试、部署等等,好处一堆堆的。 +使用 gh-pages 的原因是,我们一 push 代码的时候,就可以自动测试、部署等等,好处一堆堆的。 -接着我们需要在``package.json``里面添加脚本 +接着我们需要在 ``package.json`` 里面添加脚本 ```javascript "scripts": { @@ -735,7 +735,7 @@ branches: } ``` -这样当我们push代码的时候便会自动跑所有的测试。因为mocha的主要配置是用``mocha.opts``,所以我们还需要配置一下``mocha.opts`` +这样当我们 push 代码的时候便会自动跑所有的测试。因为 mocha 的主要配置是用 ``mocha.opts``,所以我们还需要配置一下 ``mocha.opts`` --reporter spec --ui bdd @@ -743,25 +743,25 @@ branches: --colors test/spec -最后的``test/spec``是指定测试的目录。 +最后的 ``test/spec`` 是指定测试的目录。 ### Jshint > JSLint定义了一组编码约定,这比ECMA定义的语言更为严格。这些编码约定汲取了多年来的丰富编码经验,并以一条年代久远的编程原则 作为宗旨:能做并不意味着应该做。JSLint会对它认为有的编码实践加标志,另外还会指出哪些是明显的错误,从而促使你养成好的 JavaScript编码习惯。 -当我们的js写得不合理的时候,这时测试就无法通过: +当我们的 JS 写得不合理的时候,这时测试就无法通过: line 5 col 25 A constructor name should start with an uppercase letter. line 21 col 62 Strings must use singlequote. -这是一种驱动写出更规范js的方法。 +这是一种驱动写出更规范 JS 的方法。 ### Mocha > Mocha 是一个优秀的JS测试框架,支持TDD/BDD,结合 should.js/expect/chai/better-assert,能轻松构建各种风格的测试用例。 -最后的效果如下所示: +最后的效果如下所示: Book,Link Book Test @@ -771,7 +771,7 @@ branches: ### 测试示例 -简单地看一下Book的测试: +简单地看一下 Book 的测试: ```javascript /* global describe, it */ @@ -810,7 +810,7 @@ describe('Book,Link', function () { }); ``` -因为我们用``require.js``来管理浏览器端,在后台写测试来测试的时候,我们也需要用他来管理我们的依赖,这也就是为什么这个测试这么长的原因,多数情况下一个测试类似于这样子的。(用Jasmine似乎会是一个更好的主意,但是用习惯Jasmine了) +因为我们用 ``require.js`` 来管理浏览器端,在后台写测试来测试的时候,我们也需要用他来管理我们的依赖,这也就是为什么这个测试这么长的原因,多数情况下一个测试类似于这样子的。(用 Jasmine 似乎会是一个更好的主意,但是用习惯 Jasmine 了) ```javascript describe('Book Test', function () { @@ -836,15 +836,15 @@ it('should return book label & url', function () { - 当你写了一大堆代码,你没有意识到里面有一大堆重复。 - 当你写了一大堆测试,却不知道覆盖率有多少。 -这就是个问题了,于是偶然间看到了一个叫code climate的网站。 +这就是个问题了,于是偶然间看到了一个叫 code climate 的网站。 ### Code Climate > Code Climate consolidates the results from a suite of static analysis tools into a single, real-time report, giving your team the information it needs to identify hotspots, evaluate new approaches, and improve code quality. -Code Climate整合一组静态分析工具的结果到一个单一的,实时的报告,让您的团队需要识别热点,探讨新的方法,提高代码质量的信息。 +Code Climate 整合一组静态分析工具的结果到一个单一的,实时的报告,让您的团队需要识别热点,探讨新的方法,提高代码质量的信息。 -简单地来说: +简单地来说: - 对我们的代码评分 - 找出代码中的坏味道 @@ -864,13 +864,13 @@ B | lib/rest/rest_helper.js | 19 | 62 | 3 | 4.7 | 37.5% | 2 A | lib/rest/rest_server.js | 17 | 0 | 2 | 8.6 | 88.9% | 0 A | lib/url_handler.js | 9 | 0 | 5 | 2.2 | 94.1% | 0 -分享得到的最后的结果是: +分享得到的最后的结果是: ![Coverage][1] ### 代码的坏味道 -于是我们就打开``lib/database/sqlite_helper.js``,因为其中有两个坏味道 +于是我们就打开 ``lib/database/sqlite_helper.js``,因为其中有两个坏味道 Similar code found in two :expression_statement nodes (mass = 86) @@ -1024,7 +1024,7 @@ Git 提交信息及几种不同的规范 示例 2,``[SkillTree] detail: add link data``。其中的 ``SkillTree`` 表示修改的是技能树 Tab 下的内容,``detail`` 则表示修改的是详情页,``add link data`` 则表示是添加了技能的数据 -这样做的主要原因是,它可以轻松也帮我**filter 出相应业务的内容**。 +这样做的主要原因是,它可以轻松也帮我 **filter 出相应业务的内容**。 缺点:要这样做需要团队达到一致,因此付出一些额外的成本。 @@ -1051,15 +1051,15 @@ Git 提交信息及几种不同的规范 对应的类型有: - - build: 影响构建系统或外部依赖关系的更改(示例范围:gulp,broccoli,npm) - - ci: 更改我们的持续集成文件和脚本(示例范围:Travis,Circle,BrowserStack,SauceLabs) - - docs: 仅文档更改 - - feat: 一个新功能 - - fix: 修复错误 - - perf: 改进性能的代码更改 - - refactor: 代码更改,既不修复错误也不添加功能 - - style: 不影响代码含义的变化(空白,格式化,缺少分号等) - - test: 添加缺失测试或更正现有测试 + - build:影响构建系统或外部依赖关系的更改(示例范围:gulp,broccoli,npm) + - ci:更改我们的持续集成文件和脚本(示例范围:Travis,Circle,BrowserStack,SauceLabs) + - docs:仅文档更改 + - feat:一个新功能 + - fix:修复错误 + - perf:改进性能的代码更改 + - refactor:代码更改,既不修复错误也不添加功能 + - style:不影响代码含义的变化(空白,格式化,缺少分号等) + - test:添加缺失测试或更正现有测试 同时还对应了 20+ 的 Scope,可以说这种提交比上面的提交更有挑战。 @@ -1083,13 +1083,13 @@ Git 提交信息及几种不同的规范 ## README -README通常会显示在GitHub项目的下面,如下图所示: +README 通常会显示在 GitHub 项目的下面,如下图所示: ![GitHub README](./img/readme-example.png) -通常一个好的README会让你立马对项目产生兴趣。 +通常一个好的 README 会让你立马对项目产生兴趣。 -如下面的内容是React项目的简介: +如下面的内容是 React 项目的简介: ![React README](./img/react-intro.png) @@ -1099,7 +1099,7 @@ README通常会显示在GitHub项目的下面,如下图所示: * **Virtual DOM:** React abstracts away the DOM from you, giving a simpler programming model and better performance. React can also render on the server using Node, and it can power native apps using [React Native](https://facebook.github.io/react-native/). * **Data flow:** React implements one-way reactive data flow which reduces boilerplate and is easier to reason about than traditional data binding. -通常在这个README里,还会有: +通常在这个 README 里,还会有: * 针对人群 * 安装指南 @@ -1116,13 +1116,13 @@ README通常会显示在GitHub项目的下面,如下图所示: 在一个开源项目中,良好和专业的文档是相当重要的,有时他可能会比软件还会重要。因为如果一个开源项目好用的话,多数人可能不会去查看软件的代码。这就意味着,多数时候他在和你的文档打交道。文档一般会有:API 文档、 配置文档、帮助文档、用户手册、教程等等 -写文档的软件有很多,如Markdown、Doxygen、Docbook等等。 +写文档的软件有很多,如 Markdown、Doxygen、Docbook 等等。 ## 可用示例 一个简单上手的示例非常重要,特别是通常我们是在为着某个目的而去使用一个开源项目的是时候,我们希望能马上使用到我们的项目中。 -你希望看到的是,你打开浏览器,输入下面的代码,然后**It Works**: +你希望看到的是,你打开浏览器,输入下面的代码,然后 **It Works**: ``` var HelloMessage = React.createClass({ @@ -1143,15 +1143,15 @@ React.render( 或许你应该知道了,重构是怎样的,你也知道重构能带来什么。在我刚开始学重构和设计模式的时候,我需要去找一些好的示例,以便于我更好的学习。有时候不得不创造一些更好的场景,来实现这些功能。 -有一天,我发现当我需要我一次又一次地重复讲述某些内容,于是我就计划着把这些应该掌握的技能放到GitHub上,也就有了[Artisan Stack](https://github.com/phodal-archive/artisanstack.github.io) 计划。 +有一天,我发现当我需要我一次又一次地重复讲述某些内容,于是我就计划着把这些应该掌握的技能放到 GitHub 上,也就有了 [Artisan Stack](https://github.com/phodal-archive/artisanstack.github.io) 计划。 -每个程序员都不可避免地是一个Coder,一个没有掌握好技能的Coder,算不上是手工艺人,但是手工艺人,需要有创造性的方法。 +每个程序员都不可避免地是一个 Coder,一个没有掌握好技能的 Coder,算不上是手工艺人,但是手工艺人,需要有创造性的方法。 -## 为什么重构? +## 为什么重构? > 为了更好的代码。 -在经历了一年多的工作之后,我平时的主要工作就是修Bug。刚开始的时候觉得无聊,后来才发现修Bug需要更好的技术。有时候你可能要面对着一坨一坨的代码,有时候你可能要花几天的时间去阅读代码。而你重写那几十行代码可能只会花上你不到一天的时间。但是如果你没办法理解当时为什么这么做,你的修改只会带来更多的Bug。修Bug,更多的是维护代码。还是前人总结的那句话对: +在经历了一年多的工作之后,我平时的主要工作就是修 Bug。刚开始的时候觉得无聊,后来才发现修 Bug 需要更好的技术。有时候你可能要面对着一坨一坨的代码,有时候你可能要花几天的时间去阅读代码。而你重写那几十行代码可能只会花上你不到一天的时间。但是如果你没办法理解当时为什么这么做,你的修改只会带来更多的 Bug。修 Bug,更多的是维护代码。还是前人总结的那句话对: > 写代码容易,读代码难。 @@ -1163,13 +1163,13 @@ React.render( 让我们来看看我们的第一个训练,相当有挑战性。 -## 重构uMarkdown +## 重构 uMarkdown -代码及setup请见github: [js-refactor](https://github.com/artisanstack/js-refactor) +代码及 setup 请见 GitHub:[js-refactor](https://github.com/artisanstack/js-refactor) ### 代码说明 -``uMarkdown``是一个用于将Markdown转化为HTML的库。代码看上去就像一个很典型的过程代码: +``uMarkdown`` 是一个用于将 Markdown 转化为HTML的库。代码看上去就像一个很典型的过程代码: ```javascript /* code */ @@ -1189,11 +1189,11 @@ while ((stra = micromarkdown.regexobject.mail.exec(str)) !== null) { } ``` -选这个做重构的开始,不仅仅是因为之前在写[EchoesWorks](https://github.com/phodal/echoesworks)的时候进行了很多的重构。而且它更适合于``重构到设计模式``的理论。让我们在重构完之后,给作者进行pull request吧。 +选这个做重构的开始,不仅仅是因为之前在写 [EchoesWorks](https://github.com/phodal/echoesworks) 的时候进行了很多的重构。而且它更适合于``重构到设计模式``的理论。让我们在重构完之后,给作者进行 pull request 吧。 -Markdown的解析过程,有点类似于``Pipe and Filters``模式(架构模式)。 +Markdown 的解析过程,有点类似于``Pipe and Filters``模式(架构模式)。 -Filter即我们在代码中看到的正规表达式集: +Filter 即我们在代码中看到的正规表达式集: ```javascript regexobject: { @@ -1201,13 +1201,13 @@ regexobject: { code: /\s\`\`\`\n?([^`]+)\`\`\`/g ``` -他会匹配对应的Markdown类型,随后进行替换和处理。而``str``,就是管理口的输入和输出。 +他会匹配对应的 Markdown 类型,随后进行替换和处理。而``str``,就是管理口的输入和输出。 接着,我们就可以对其进行简单的重构。 -(ps: 推荐用WebStrom来做重构,自带重构功能) +(PS:推荐用 WebStrom 来做重构,自带重构功能) -作为一个示例,我们先提出codeHandler方法,即将上面的 +作为一个示例,我们先提出 codeHandler 方法,即将上面的 ```javascript /* code */ @@ -1224,7 +1224,7 @@ codeFilter: function (str, stra) { }, ``` -while语句就成了 +while 语句就成了 ```javascript while ((stra = regexobject.code.exec(str)) !== null) { @@ -1238,7 +1238,7 @@ while ((stra = regexobject.code.exec(str)) !== null) { grunt test ``` -同理我们就可以``mail``、``headline``等方法进行重构。接着就会变成类似于下面的代码, +同理我们就可以 ``mail``、``headline`` 等方法进行重构。接着就会变成类似于下面的代码, ```javascript /* code */ @@ -1262,7 +1262,7 @@ str = tableHandler(str, execStr, strict); } ``` -然后你也看到了,上面有一堆重复的代码,接着让我们用JavaScript的``奇技淫巧``,即apply方法,把上面的重复代码变成。 +然后你也看到了,上面有一堆重复的代码,接着让我们用 JavaScript 的``奇技淫巧``,即apply方法,把上面的重复代码变成。 ```javascript ['code', 'headline', 'lists', 'tables', 'links', 'mail', 'url', 'smlinks', 'hr'].forEach(function (type) { @@ -1286,20 +1286,20 @@ str = tableHandler(str, execStr, strict); ✓ should return correctly class name ``` -快来试试吧, [https://github.com/artisanstack/js-refactor](https://github.com/artisanstack/js-refactor) +快来试试吧,[https://github.com/artisanstack/js-refactor](https://github.com/artisanstack/js-refactor) -是时候讨论这个Refactor利器了,最初看到这个重构的过程是从ThoughtWorks郑大晔校开始的,只是之前对于Java的另外一个编辑器Eclipse的坏感。。这些在目前已经不是很重要了,试试这个公司里面应用广泛的编辑器。 +是时候讨论这个 Refactor 利器了,最初看到这个重构的过程是从 ThoughtWorks 郑大晔校开始的,只是之前对于 Java 的另外一个编辑器 Eclipse 的坏感。。这些在目前已经不是很重要了,试试这个公司里面应用广泛的编辑器。 -## Intellij Idea重构 +## Intellij Idea 重构 开发的流程大致就是这样子的,测试先行算是推荐的。 编写测试->功能代码->修改测试->重构 -上次在和buddy聊天的时候,才知道测试在功能简单的时候是后行的,在功能复杂不知道怎么下手的时候是先行的。 +上次在和 buddy 聊天的时候,才知道测试在功能简单的时候是后行的,在功能复杂不知道怎么下手的时候是先行的。 -开始之前请原谅我对于Java语言的一些无知,然后,看一下我写的Main函数: +开始之前请原谅我对于 Java 语言的一些无知,然后,看一下我写的 Main 函数: ```java package com.phodal.learing; @@ -1316,16 +1316,16 @@ public class Main { } ``` -代码写得还好(自我感觉),先不管Cal和Cal2两个类。大部分都能看懂,除了c,d不知道他们表达的是什么意思,于是。 +代码写得还好(自我感觉),先不管 Cal 和 Cal2 两个类。大部分都能看懂,除了 c, d 不知道他们表达的是什么意思,于是。 ### Rename -**快捷键:Shift+F6** +**快捷键:Shift+F6** -**作用:重命名** +**作用:重命名** - - 把光标丢到int c中的c,按下shift+f6,输入result_add - - 把光标移到int d中的d,按下shift+f6,输入result_sub + - 把光标丢到 int c 中的 c,按下 Shift + F6,输入 result_add + - 把光标移到 int d 中的 d,按下 Shift + F6,输入 result_sub 于是就有 @@ -1346,13 +1346,13 @@ public class Main { ### Extract Method -**快捷键:alt+command+m** +**快捷键:Alt+command+m** -**作用:扩展方法** +**作用:扩展方法** -- 选中System.out.println(result_add); -- 按下alt+command+m -- 在弹出的窗口中输入mprint +- 选中 System.out.println(result_add); +- 按下 Alt + command + m +- 在弹出的窗口中输入 mprint 于是有了 @@ -1370,19 +1370,19 @@ private static void mprint(int result_sub) { } ``` -似乎我们不应该这样对待System.out.println,那么让我们内联回去 +似乎我们不应该这样对待 System.out.println,那么让我们内联回去 ### Inline Method -**快捷键:alt+command+n** +**快捷键:Alt + command + n** -**作用:内联方法** +**作用:内联方法** -- 选中main中的mprint -- alt+command+n -- 选中Inline all invocations and remove the method(2 occurrences) 点确定 +- 选中 main 中的 mprint +- Alt + command + n +- 选中 Inline all invocations and remove the method(2 occurrences) 点确定 -然后我们等于什么也没有做了~~: +然后我们等于什么也没有做了~~: ```java public static void main(String[] args) { @@ -1398,7 +1398,7 @@ public static void main(String[] args) { ### Pull Members Up -开始之前让我们先看看Cal2类: +开始之前让我们先看看 Cal2 类: ```java public class Cal2 extends Cal { @@ -1409,7 +1409,7 @@ public class Cal2 extends Cal { } ``` -以及Cal2的父类Cal +以及 Cal2 的父类 Cal ```java public class Cal { @@ -1421,7 +1421,7 @@ public class Cal { } ``` -最后的结果,就是将Cal2类中的sub方法,提到父类: +最后的结果,就是将 Cal2 类中的 sub 方法,提到父类: ```java public class Cal { @@ -1442,13 +1442,13 @@ public class Cal { 快捷键 -Mac: 木有 +Mac:木有 -Windows/Linux: 木有 +Windows/Linux:木有 -或者: ``Shift``+``alt``+``command``+``T`` 再选择 ``Replace Temp with Query`` +或者:``Shift``+``Alt``+``command``+``T`` 再选择 ``Replace Temp with Query`` -鼠标: **Refactor** | ``Replace Temp with Query`` +鼠标:**Refactor** | ``Replace Temp with Query`` #### 重构之前 @@ -1473,7 +1473,7 @@ public class replaceTemp { #### 重构 -选中``basePrice``很愉快地拿鼠标点上面的重构 +选中 ``basePrice`` 很愉快地拿鼠标点上面的重构 ![Replace Temp With Query](./img/replace.jpg) @@ -1523,11 +1523,11 @@ public class replaceTemp { } ``` -接着我们选中``aString``,再打开重构菜单,或者 +接着我们选中 ``aString``,再打开重构菜单,或者 -``Command``+``Alt``+``Shift``+``T`` 再选中Replace Temp with Query +``Command``+``Alt``+``Shift``+``T`` 再选中 Replace Temp with Query -便会有下面的结果: +便会有下面的结果: ```javas @@ -1551,17 +1551,17 @@ public class replaceTemp { ## TDD -虽然接触的TDD时间不算短,然而真正在实践TDD上的时候少之又少。除去怎么教人TDD,就是与人结对编程时的switch,或许是受限于当前的开发流程。 +虽然接触的 TDD 时间不算短,然而真正在实践 TDD 上的时候少之又少。除去怎么教人 TDD,就是与人结对编程时的 switch,或许是受限于当前的开发流程。 偶然间在开发一个物联网相关的开源项目——[Lan](https://github.com/phodal/lan)的时候,重拾了这个过程。不得不说提到的一点是,在我们的开发流程中**测试是由相关功能开发人员写的**,有时候测试是一种很具挑战性的工作。久而久之,为自己的开源项目写测试变成一种自然而然的事。有时没有测试,反而变得**没有安全感**。 ### 一次测试驱动开发 -之前正在重写一个[物联网](http://www.phodal.com/iot)的服务端,主要便是结合CoAP、MQTT、HTTP等协议构成一个物联网的云服务。现在,主要的任务是集中于协议与授权。由于,不同协议间的授权是不一样的,最开始的时候我先写了一个http put授权的功能,而在起先的时候是如何测试的呢? +之前正在重写一个[物联网](http://www.phodal.com/iot)的服务端,主要便是结合 CoAP、MQTT、HTTP 等协议构成一个物联网的云服务。现在,主要的任务是集中于协议与授权。由于,不同协议间的授权是不一样的,最开始的时候我先写了一个 http put 授权的功能,而在起先的时候是如何测试的呢? curl --user root:root -X PUT -d '{ "dream": 1 }' -H "Content-Type: application/json" http://localhost:8899/topics/test -我只要顺利在request中看有无``req.headers.authorization``,我便可以继续往下,接着给个判断。毕竟,我们对HTTP协议还是蛮清楚的。 +我只要顺利在 request 中看有无 ``req.headers.authorization``,我便可以继续往下,接着给个判断。毕竟,我们对 HTTP 协议还是蛮清楚的。 ```javascript if (!req.headers.authorization) { @@ -1571,13 +1571,13 @@ if (!req.headers.authorization) { } ``` -可是除了HTTP协议,还有MQTT和CoAP。对于MQTT协议来说,那还算好,毕竟自带授权,如: +可是除了 HTTP 协议,还有 MQTT 和 CoAP。对于 MQTT 协议来说,那还算好,毕竟自带授权,如: ```bash mosquitto_pub -u root -P root -h localhost -d -t lettuce -m "Hello, MQTT. This is my first message." ``` -便可以让我们简单地完成这个功能,然而有的协议是没有这样的功能如CoAP协议中是用Option来进行授权的。现在的工具如libcoap只能有如下的简单功能 +便可以让我们简单地完成这个功能,然而有的协议是没有这样的功能如 CoAP 协议中是用 Option 来进行授权的。现在的工具如 libcoap 只能有如下的简单功能 ```bash coap-client -m get coap://127.0.0.1:5683/topics/zero -T @@ -1600,48 +1600,48 @@ req.setOption('Block2', [new Buffer('phodal'), new Buffer('phodal')]); req.end(); ``` -写完测试脚本后发现不对了,这个不应该是测试的代码吗? 于是将其放到了spec中,接着发现了上面的全部功能的实现过程为什么不用TDD实现呢? +写完测试脚本后发现不对了,这个不应该是测试的代码吗?于是将其放到了 spec 中,接着发现了上面的全部功能的实现过程为什么不用 TDD 实现呢? -### 说说TDD +### 说说 TDD 测试驱动开发是一个很"古老"的程序开发方法,然而由于国内的开发流程的问题——即开发人员负责功能的测试,导致这么好的一项技术没有在国内推广。 -测试驱动开发的主要过程是: +测试驱动开发的主要过程是: 1. 先写功能的测试 2. 实现功能代码 -3. 提交代码(commit -> 保证功能正常) +3. 提交代码(commit -> 保证功能正常) 4. 重构功能代码 -而对于这样的一个物联网项目来说,我已经有了几个有利的前提: +而对于这样的一个物联网项目来说,我已经有了几个有利的前提: 1. 已经有了原型 2. 框架设计 -### TDD思考 +### TDD 思考 -通常在我的理解下,TDD是可有可无的。既然我知道了我要实现的大部分功能,而且我也知道如何实现。与此同时,对Code Smell也保持着警惕、要保证功能被测试覆盖。那么,总的来说TDD带来的价值并不大。 +通常在我的理解下,TDD 是可有可无的。既然我知道了我要实现的大部分功能,而且我也知道如何实现。与此同时,对 Code Smell 也保持着警惕、要保证功能被测试覆盖。那么,总的来说 TDD 带来的价值并不大。 -然而,在当前这种情况下,我知道我想要的功能,但是我并不理解其深层次的功能。我需要花费大量的时候来理解,它为什么是这样的,需要先有一些脚本来知道它是怎么工作的。TDD变显得很有价值,换句话来说,在现有的情况下,TDD对于我们不了解的一些事情,可以驱动出更多的开发。毕竟在我们完成测试脚本之后,我们也会发现这些测试脚本成为了代码的一部分。 +然而,在当前这种情况下,我知道我想要的功能,但是我并不理解其深层次的功能。我需要花费大量的时候来理解,它为什么是这样的,需要先有一些脚本来知道它是怎么工作的。TDD 变显得很有价值,换句话来说,在现有的情况下,TDD 对于我们不了解的一些事情,可以驱动出更多的开发。毕竟在我们完成测试脚本之后,我们也会发现这些测试脚本成为了代码的一部分。 -在这种理想的情况下,我们为什么不TDD呢? +在这种理想的情况下,我们为什么不 TDD 呢? ## 功能测试 -### 轻量级网站测试TWill +### 轻量级网站测试 TWill > twill was initially designed for testing Web sites, although since then people have also figured out that it's good for browsing unsuspecting Web sites. -之所以说轻量的原因是他是拿命令行测试的,还有DSL,还有Python。 +之所以说轻量的原因是他是拿命令行测试的,还有 DSL,还有 Python。 除此之外,还可以拿它做压力测试,这种压力测试和一般的不一样。可以模拟整个过程,比如同时有多少人登陆你的网站。 -不过,它有一个限制是没有JavaScript。 +不过,它有一个限制是没有 JavaScript。 -看了一下源码,大概原理就是用``requests``下载html,接着用``lxml``解析html,比较有意思的是内嵌了一个``DSL``。 +看了一下源码,大概原理就是用 ``requests`` 下载 html,接着用 ``lxml`` 解析 html,比较有意思的是内嵌了一个 ``DSL``。 -这是一个Python的库。 +这是一个 Python 的库。 pip install twill @@ -1649,7 +1649,7 @@ req.end(); 1.启动我们的应用。 -2.进入twill shell +2.进入 twill shell twill-sh -= Welcome to twill! =- @@ -1680,7 +1680,7 @@ req.end(); fv 1 email test@tes.com fv 1 password test -6.修改action +6.修改 action formaction 1 http://127.0.0.1:5000/login @@ -1694,7 +1694,7 @@ req.end(); ### Twill 测试脚本 -当然我们也可以用脚本直接来测试``login.twill``: +当然我们也可以用脚本直接来测试 ``login.twill``: go http://127.0.0.1:5000/login @@ -1742,11 +1742,11 @@ req.end(); ## Fake Server -实践了一下怎么用sinon去fake server,还没用respondWith,于是写一下。 +实践了一下怎么用 sinon 去 fake server,还没用 respondWith,于是写一下。 -这里需要用到sinon框架来测试。 +这里需要用到 sinon 框架来测试。 -当我们fetch的时候,我们就可以返回我们想要fake的结果。 +当我们 fetch 的时候,我们就可以返回我们想要 fake 的结果。 var data = {"id":1,"name":"Rice","type":"Good","price":12,"quantity":1,"description":"Made in China"}; beforeEach(function() { @@ -1763,13 +1763,13 @@ req.end(); ); }); -于是在 afterEach 的时候,我们需要恢复这个server。 +于是在 afterEach 的时候,我们需要恢复这个 server。 afterEach(function() { this.server.restore(); }); -接着写一个jasmine测试来测试 +接着写一个 jasmine 测试来测试 describe("Collection Test", function() { it("should get data from the url", function() { @@ -1789,7 +1789,7 @@ req.end(); 如何推广 === -除了擅长编写 md 电子书来攒 star,我还写了一系列的开源软件,也掌握了一些项目运营的技巧。 +除了擅长编写 md 电子书来攒 Star,我还写了一系列的开源软件,也掌握了一些项目运营的技巧。 **开源并不是你把软件、README 写好就行了,还有详细的文档、示例程序等等**。 @@ -1817,13 +1817,13 @@ Vue 不是因为好用,而一下子火了。这一点我印象特别深,当 除此,文中还提到了一篇文章《[How to Spread The Word About Your Code](https://hacks.mozilla.org/2013/05/how-to-spread-the-word-about-your-code/?utm_source=statuscode&utm_medium=email)》 。 -这一点相当的有意思,如果你的想法好的话,那么大家都会肯定,点下链接,为你来个 star。那么,你就获得更好的动力去做这件事。项目也在开头的时候,获得了相当多的关注。而如果大家觉得你的项目没有新意的话,那么你懂的~。 +这一点相当的有意思,如果你的想法好的话,那么大家都会肯定,点下链接,为你来个 Star。那么,你就获得更好的动力去做这件事。项目也在开头的时候,获得了相当多的关注。而如果大家觉得你的项目没有新意的话,那么你懂的~。 -除此,还有一种可能是,你的 ID 不够 fancy,即你在社区的影响上比较少。此时,就需要**一点点慢慢积累人气**了。当你积累了一些人气,你就能和松本行弘一样,在创建 mRuby 的时候就有 1000+ 的 star。并且,在社区上还有一些相关的文章介绍,各个头条也由他的粉丝发了上去。如,一年多以前,我创建了 [mole](https://github.com/phodal/mole) 项目。 +除此,还有一种可能是,你的 ID 不够 fancy,即你在社区的影响上比较少。此时,就需要**一点点慢慢积累人气**了。当你积累了一些人气,你就能和松本行弘一样,在创建 mRuby 的时候就有 1000+ 的 Star。并且,在社区上还有一些相关的文章介绍,各个头条也由他的粉丝发了上去。如,一年多以前,我创建了 [mole](https://github.com/phodal/mole) 项目。 ![Mole](./img/mole.png) -当时,是为了给自己做一个基于 GitHub 云笔记的工具,在完成度到一定程度的时候。我在我的微信公从号上发了相关的介绍,第二天就有 100+ 的 star 了,还接收至最一些鼓舞的话语。对应于国内则有: +当时,是为了给自己做一个基于 GitHub 云笔记的工具,在完成度到一定程度的时候。我在我的微信公从号上发了相关的介绍,第二天就有 100+ 的 Star 了,还接收到一些鼓舞的话语。对应于国内则有: - 极客头条 - 掘金 @@ -1893,7 +1893,7 @@ numbers, objects, strings, etc. Lodash’s modular methods are great for: 当然了,这种事不能太过,要不然会招来一堆黑。 -### 安装及hello, world 示例 +### 安装及 hello, world 示例 在我们看完了上面的介绍之后,紧接着接一个 hello, world 的示例。在运行 hello, world 之前,我们可能需要一些额外的安装工作,如: @@ -1950,7 +1950,7 @@ WTF! ![Lodash 示例](./img/lodash-code-example.png) -上图是使用了 jsdoc 的 Lodash 示例。 +上图是使用了 JSDoc 的 Lodash 示例。 除了上面的示例,我们还可以录制一些视频,写一些文章说明项目的思考、架构等等。 @@ -2130,11 +2130,11 @@ Set up your git name and email, this is important so that your commits can be id ![Gource 历史](./img/gource.jpg) -# GitHub用户分析 +# GitHub 用户分析 ## 生成图表 -如何分析用户的数据是一个有趣的问题,特别是当我们有大量的数据的时候。除了``matlab``,我们还可以用``numpy``+``matplotlib`` +如何分析用户的数据是一个有趣的问题,特别是当我们有大量的数据的时候。除了 ``matlab``,我们还可以用 ``numpy`` + ``matplotlib`` 数据可以在这边寻找到 @@ -2144,11 +2144,11 @@ Set up your git name and email, this is important so that your commits can be id ![2014 01 01](./img/2014-01-01.png) -要解析的json文件位于``data/2014-01-01-0.json``,大小6.6M,显然我们可能需要用每次只读一行的策略,这足以解释为什么诸如sublime打开的时候很慢,而现在我们只需要里面的json数据中的创建时间。。 +要解析的 JSON 文件位于``data/2014-01-01-0.json``,大小 6.6M,显然我们可能需要用每次只读一行的策略,这足以解释为什么诸如 sublime 打开的时候很慢,而现在我们只需要里面的 JSON 数据中的创建时间。。 ==, 这个文件代表什么? -**2014年1月1日零时到一时,用户在github上的操作,这里的用户指的是很多。。一共有4814条数据,从commit、create到issues都有。** +**2014年1月1日零时到一时,用户在 GitHub 上的操作,这里的用户指的是很多。。一共有 4814 条数据,从 commit、create 到 issues 都有。** ### 数据解析 @@ -2158,7 +2158,7 @@ for line in open(jsonfile): line = f.readline() ``` -然后再解析json +然后再解析 JSON ```python import dateutil.parser @@ -2167,7 +2167,7 @@ lin = json.loads(line) date = dateutil.parser.parse(lin["created_at"]) ``` -这里用到了``dateutil``,因为新鲜出炉的数据是string需要转换为``dateutil``,再到数据放到数组里头。最后有就有了``parse_data`` +这里用到了 ``dateutil``,因为新鲜出炉的数据是 string 需要转换为 ``dateutil``,再到数据放到数组里头。最后有就有了 ``parse_data`` ```python def parse_data(jsonfile): @@ -2272,13 +2272,13 @@ draw_date("data/2014-01-01-0.json") ![Phodal Huang's Report](./img/phodal-results.png) -这是我的每周情况,显然如果把星期六移到前面的话,随着工作时间的增长,在github上的使用在下降,作为一个 +这是我的每周情况,显然如果把星期六移到前面的话,随着工作时间的增长,在 GitHub 上的使用在下降,作为一个 a fulltime hacker who works best in the evening (around 8 pm). -不过这个是osrc的分析结果。 +不过这个是 osrc 的分析结果。 -### python github 每周情况分析 +### Python GitHub 每周情况分析 看一张分析后的结果 @@ -2309,7 +2309,7 @@ draw_date("data/2014-01-01-0.json") ├── 2014-02-19-0.json └── 2014-02-20-0.json -我们获取是每天晚上0点时的情况,至于为什么是0点,我想这里的数据量可能会比较少。除去1月1号的情况,就是上面的结果,在只有一周的情况时,总会以为因为在国内那时是假期,但是总觉得不是很靠谱,国内的程序员虽然很多,会在github上活跃的可能没有那么多,直至列出每一周的数据时。 +我们获取是每天晚上0点时的情况,至于为什么是0点,我想这里的数据量可能会比较少。除去1月1号的情况,就是上面的结果,在只有一周的情况时,总会以为因为在国内那时是假期,但是总觉得不是很靠谱,国内的程序员虽然很多,会在 GitHub 上活跃的可能没有那么多,直至列出每一周的数据时。 6570, 7420, 11274, 12073, 12160, 12378, 12897, 8474, 7984, 12933, 13504, 13763, 13544, 12940, @@ -2391,7 +2391,7 @@ if __name__ == '__main__': ### SQLite3 -我们创建了一个名为``userdata.db``的数据库文件,然后创建了一个表,里面有owner,language,eventtype,name url +我们创建了一个名为 ``userdata.db`` 的数据库文件,然后创建了一个表,里面有 owner, language, eventtype, name url ```python def init_db(): @@ -2414,7 +2414,7 @@ def get_count(username): return count, userinfo ``` -当我查询``gmszone``的时候,也就是我自己就会有如下的结果 +当我查询 ``gmszone`` 的时候,也就是我自己就会有如下的结果 ```bash (u'gmszone', u'ForkEvent', u'RESUME', u'TeX', u'https://github.com/gmszone/RESUME') @@ -2429,9 +2429,9 @@ def get_count(username): 109 ```` -一共有109个事件,有``Watch``,``Create``,``Push``,``Fork``还有其他的, -项目主要有``iot``,``RESUME``,``iot-dashboard``,``wechat-wordpress``, -接着就是语言了,``Tex``,``Javascript``,``Ruby``,接着就是项目的url了。 +一共有109个事件,有 ``Watch``, ``Create``, ``Push``, ``Fork`` 还有其他的, +项目主要有``iot``, ``RESUME``, ``iot-dashboard``, ``wechat-wordpress``, +接着就是语言了,``Tex``, ``Javascript``, ``Ruby``,接着就是项目的 url 了。 值得注意的是。 @@ -2439,9 +2439,9 @@ def get_count(username): -rw-r--r-- 1 fdhuang staff 905M Apr 12 14:59 userdata.db ``` -这个数据库文件有**905M**,不过查询结果相当让人满意,至少相对于原来的结果来说。 +这个数据库文件有 **905M**,不过查询结果相当让人满意,至少相对于原来的结果来说。 -Python自带了对SQLite3的支持,然而我们还需要安装SQLite3 +Python 自带了对 SQLite3 的支持,然而我们还需要安装 SQLite3 ```bash brew install sqlite3 @@ -2453,23 +2453,23 @@ brew install sqlite3 sudo port install sqlite3 ``` -或者是Ubuntu的 +或者是 Ubuntu 的 ```bash sudo apt-get install sqlite3 ``` -openSUSE自然就是 +openSUSE 自然就是 ```bash sudo zypper install sqlite3 ``` -不过,用yast2也很不错,不是么。。 +不过,用 yast2 也很不错,不是么。。 ### 数据导入 -需要注意的是这里是需要python2.7,起源于对gzip的上下文管理器的支持问题 +需要注意的是这里是需要 Python 2.7,起源于对 gzip 的上下文管理器的支持问题 ```python def handle_gzip_file(filename): @@ -2521,11 +2521,11 @@ def build_db_with_gzip(): c.close() ``` -``executemany``可以插入多条数据,对于我们的数据来说,一小时的文件大概有五六千个会符合我们上面的安装,也就是有``actor``又有``type``才是我们需要记录的数据,我们只需要统计用户的那些事件,而非全部的事件。 +``executemany`` 可以插入多条数据,对于我们的数据来说,一小时的文件大概有五六千个会符合我们上面的安装,也就是有 ``actor`` 又有 ``type`` 才是我们需要记录的数据,我们只需要统计用户的那些事件,而非全部的事件。 -我们需要去遍历文件,然后找到合适的部分,这里只是要找``2014-03-01``到``2014-03-31``的全部事件,而光这些数据的gz文件就有1.26G,同上面那些解压为json文件显得不合适,只能用遍历来处理。 +我们需要去遍历文件,然后找到合适的部分,这里只是要找``2014-03-01``到``2014-03-31``的全部事件,而光这些数据的 gz 文件就有 1.26G,同上面那些解压为 JSON 文件显得不合适,只能用遍历来处理。 -这里参考了osrc项目中的写法,或者说直接复制过来。 +这里参考了 osrc 项目中的写法,或者说直接复制过来。 首先是正规匹配 @@ -2533,11 +2533,11 @@ def build_db_with_gzip(): date_re = re.compile(r"([0-9]{4})-([0-9]{2})-([0-9]{2})-([0-9]+)\.json.gz") ``` -不过主要的还是在于``glob.glob`` +不过主要的还是在于 ``glob.glob`` -> glob是python自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,就类似于Windows下的文件搜索,支持通配符操作。 +> glob是 Python 自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,就类似于Windows下的文件搜索,支持通配符操作。 -这里也就用上了``gzip.GzipFile``又一个不错的东西。 +这里也就用上了 ``gzip.GzipFile`` 又一个不错的东西。 最后代码可以见 @@ -2557,7 +2557,7 @@ pipe.zscore('osrc:user',"gmszone") pipe.execute() ``` -系统返回了``227.0``,试试别人。 +系统返回了 ``227.0``,试试别人。 ```bash >>> pipe.zscore('osrc:user',"dfm") @@ -2576,7 +2576,7 @@ pipe.execute() [{'1': '51', '0': '41', '3': '17', '2': '34', '5': '28', '4': '22', '6': '34'}] ``` -结果大致如下图所示: +结果大致如下图所示: ![SMTWTFS](./img/smtwtfs.png) @@ -2590,9 +2590,9 @@ pipe.execute() ![Main Event](./img/main-events.png) -蓝色的就是push事件,黄色的是create等等。 +蓝色的就是 push 事件,黄色的是 create 等等。 -到这里我们算是知道了OSRC的数据库部分是如何工作的。 +到这里我们算是知道了 OSRC 的数据库部分是如何工作的。 #### Redis 查询 @@ -2635,13 +2635,13 @@ def get_vector(user, pipe=None): ['alesdokshanin', 'hjiawei', 'andrewreedy', 'christj6', '1995eaton'] ``` -osrc最有意思的一部分莫过于flann,当然说的也是系统后台的设计的一个很关键及有意思的部分。 +osrc 最有意思的一部分莫过于 flann,当然说的也是系统后台的设计的一个很关键及有意思的部分。 ## 邻近算法与相似用户 邻近算法是在这个分析过程中一个很有意思的东西。 ->邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法可以说是整个数据挖掘分类技术中最简单的方法了。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用她最接近的k个邻居来代表。 +>邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法可以说是整个数据挖掘分类技术中最简单的方法了。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用她最接近的k个邻居来代表。 换句话说,我们需要一些样本来当作我们的分析资料,这里东西用到的就是我们之前的。 @@ -2649,7 +2649,7 @@ osrc最有意思的一部分莫过于flann,当然说的也是系统后台的 [227.0, {'1': '51', '0': '41', '3': '17', '2': '34', '5': '28', '4': '22', '6': '34'}, [('PushEvent', 154.0), ('CreateEvent', 41.0), ('WatchEvent', 18.0), ('GollumEvent', 8.0), ('MemberEvent', 3.0), ('ForkEvent', 2.0), ('ReleaseEvent', 1.0)], 0, 0, 0, 11, [('CSS', 74.0), ('JavaScript', 60.0), ('Ruby', 12.0), ('TeX', 6.0), ('Python', 6.0), ('Java', 5.0), ('C++', 5.0), ('Assembly', 5.0), ('C', 3.0), ('Emacs Lisp', 2.0), ('Arduino', 2.0)]] ``` -在代码中是构建了一个points.h5的文件来分析每个用户的points,之后再记录到hdf5文件中。 +在代码中是构建了一个 points.h5 的文件来分析每个用户的 points,之后再记录到 hdf5 文件中。 ``` [ 0.00438596 0.18061674 0.2246696 0.14977974 0.07488987 0.0969163 @@ -2664,14 +2664,14 @@ osrc最有意思的一部分莫过于flann,当然说的也是系统后台的 0. 0. 0. 0. 0.00881057] ``` -这里分析到用户的大部分行为,再找到与其行为相近的用户,主要的行为有下面这些: +这里分析到用户的大部分行为,再找到与其行为相近的用户,主要的行为有下面这些: - 每星期的情况 - 事件的类型 - 贡献的数量,连接以及语言 - 最多的语言 -osrc中用于解析的代码 +osrc 中用于解析的代码 ```python def parse_vector(results): @@ -2708,7 +2708,7 @@ def parse_vector(results): return points ``` -这样也就返回我们需要的点数,然后我们可以用``get_points``来获取这些 +这样也就返回我们需要的点数,然后我们可以用 ``get_points`` 来获取这些 ```python def get_points(usernames): @@ -2738,48 +2738,48 @@ def get_points(usernames): 真看不出来两者有什么相似的地方 。。。。 -如何在GitHub"寻找灵感(fork)" +如何在 GitHub "寻找灵感(fork)" === > 重造轮子是重新创造一个已有的或是已被其他人优化的基本方法。 -最近萌发了一个想法写游戏引擎,之前想着做一个JavaScript前端框架。看看,这个思路是怎么来的。 +最近萌发了一个想法写游戏引擎,之前想着做一个 JavaScript 前端框架。看看,这个思路是怎么来的。 -## Lettuce构建过程 +## Lettuce 构建过程 -> Lettuce是一个简约的移动开发框架。 +> Lettuce 是一个简约的移动开发框架。 -故事的出发点是这样的:``写了很多代码,用的都是框架,最后不知道收获什么了``?事实也是如此,当自己做了一些项目之后,发现最后什么也没有收获到。于是,就想着做一个框架。 +故事的出发点是这样的:``写了很多代码,用的都是框架,最后不知道收获什么了``?事实也是如此,当自己做了一些项目之后,发现最后什么也没有收获到。于是,就想着做一个框架。 ### 需求 有这样的几个前提 - - 为什么我只需要jQuery里的选择器、Ajax要引入那么重的库呢? - - 为什么我只需要一个Template,却想着用Mustache - - 为什么我需要一个Router,却要用Backbone呢? - - 为什么我需要的是一个isObject函数,却要用到整个Underscore? + - 为什么我只需要 jQuery 里的选择器、Ajax 要引入那么重的库呢? + - 为什么我只需要一个 Template,却想着用 Mustache + - 为什么我需要一个 Router,却要用 Backbone 呢? + - 为什么我需要的是一个 isObject 函数,却要用到整个 Underscore? 我想要的只是一个简单的功能,而我不想引入一个庞大的库。换句话说,我只需要不同库里面的一小部分功能,而不是一个库。 -实际上想要的是: +实际上想要的是: > 构建一个库,里面从不同的库里面抽取出不同的函数。 ### 计划 -这时候我参考了一本电子书《Build JavaScript FrameWork》,加上一些平时的需求,于是很快的就知道自己需要什么样的功能: +这时候我参考了一本电子书《Build JavaScript FrameWork》,加上一些平时的需求,于是很快的就知道自己需要什么样的功能: - Promise 支持 - - Class类(ps:没有一个好的类使用的方式) + - Class类(PS:没有一个好的类使用的方式) - Template 一个简单的模板引擎 - Router 用来控制页面的路由 - - Ajax 基本的Ajax Get/Post请求 + - Ajax 基本的 Ajax Get/Post 请求 -在做一些实际的项目中,还遇到了这样的一些功能支持: +在做一些实际的项目中,还遇到了这样的一些功能支持: - Effect 简单的一些页面效果 - - AMD支持 + - AMD 支持 而我们有一个前提是要保持这个库尽可能的小、同时我们还需要有测试。 @@ -2789,14 +2789,14 @@ def get_points(usernames): #### 生成框架 -因为Yeoman可以生成一个简单的轮廓,所以我们可以用它来生成这个项目的骨架。 +因为 Yeoman 可以生成一个简单的轮廓,所以我们可以用它来生成这个项目的骨架。 - Gulp - Jasmine #### 寻找 -在GitHub上搜索了一个看到了下面的几个结果: +在 GitHub 上搜索了一个看到了下面的几个结果: - [https://github.com/then/promise](https://github.com/then/promise) - [https://github.com/reactphp/promise](https://github.com/reactphp/promise) @@ -2804,7 +2804,7 @@ def get_points(usernames): - [https://github.com/petkaantonov/bluebird](https://github.com/petkaantonov/bluebird) - [https://github.com/cujojs/when](https://github.com/cujojs/when) -但是显然,他们都太重了。事实上,对于一个库来说,80%的人只需要其中20%的代码。于是,找到了[https://github.com/stackp/promisejs](https://github.com/stackp/promisejs),看了看用法,这就是我们需要的功能: +但是显然,他们都太重了。事实上,对于一个库来说,80% 的人只需要其中 20% 的代码。于是,找到了[https://github.com/stackp/promisejs](https://github.com/stackp/promisejs),看了看用法,这就是我们需要的功能: ```javascript function late(n) { @@ -2834,7 +2834,7 @@ late(100).then( ); ``` -接着打开看看Promise对象,有我们需要的功能,但是又有一些功能超出我的需求。接着把自己不需要的需求去掉,这里函数最后就变成了 +接着打开看看 Promise 对象,有我们需要的功能,但是又有一些功能超出我的需求。接着把自己不需要的需求去掉,这里函数最后就变成了 ```javascript function Promise() { @@ -2871,7 +2871,7 @@ var promise = { }; ``` -需要注意的是: ``License``,不同的软件有不同的License,如MIT、GPL等等。最好能在遵循协议的情况下,使用别人的代码。 +需要注意的是:``License``,不同的软件有不同的 License,如 MIT、GPL 等等。最好能在遵循协议的情况下,使用别人的代码。 ### 实现第二个需求 @@ -2917,9 +2917,9 @@ Lettuce.send = function (url, method, callback, data) { 我们并不建议所有的读者都直接看最新的代码,正确的姿势应该是: -- clone某个项目的代码到本地 -- 查看这个项目的release列表 -- 找到一个看得懂的release版本,如1.0或者更早的版本 +- clone 某个项目的代码到本地 +- 查看这个项目的 release 列表 +- 找到一个看得懂的 release 版本,如 1.0 或者更早的版本 - 读懂上一个版本的代码 - 向后阅读大版本的源码 - 读最新的源码 @@ -2928,30 +2928,30 @@ Lettuce.send = function (url, method, callback, data) { ## 阅读过程 -在我阅读的前端库、Python后台库的过程中,我们都是以造轮子为目的展开的。所以在最开始的时候,我需要一个可以工作,并且拥有我想要的功能的版本。 +在我阅读的前端库、Python 后台库的过程中,我们都是以造轮子为目的展开的。所以在最开始的时候,我需要一个可以工作,并且拥有我想要的功能的版本。 ![it-works-cms.png](./img/it-works-cms.png) -紧接着,我就可以开始去实践这个版本中的一些功能,并理解他们是怎么工作的。再用`git`大法展开之前修改的内容,可以使用IDE自带的Diff工具: +紧接着,我就可以开始去实践这个版本中的一些功能,并理解他们是怎么工作的。再用 `git` 大法展开之前修改的内容,可以使用 IDE 自带的 Diff 工具: ![pycharm-diff.jpg](./img/pycharm-diff.jpg) -或者类似于`SourceTree`这样的工具,来查看修改的内容。 +或者类似于 `SourceTree` 这样的工具,来查看修改的内容。 在我们理解了基本的核心功能后,我们就可以向后查看大、中版本的更新内容了。 开始之前,我们希望大家对版本号管理有一些基本的认识。 ## 版本号管理 -我最早阅读的开始软件是Linux,而下面则是Linux的Release过程: +我最早阅读的开始软件是 Linux,而下面则是 Linux 的 Release 过程: ![linux-history.png](./img/linux-history.png) 表格源自一本书叫《Linux内核0.11(0.95)完全注释》,简单地再介绍一下: -- 版本0.00是一个hello,world程序 -- 版本0.01包含了可以工作的代码 -- 版本0.11是基本可以正常的版本 +- 版本 0.00 是一个 hello, world 程序 +- 版本 0.01 包含了可以工作的代码 +- 版本 0.11 是基本可以正常的版本 这里就要扯到《GNU 风格的版本号管理策略》: @@ -2964,144 +2964,144 @@ Lettuce.send = function (url, method, callback, data) { 因此,我们可以得到几个简单的结论: - 我们需要阅读最早的有核心代码的版本 -- 我们需要阅读1.0版本的Release -- 往后每一次大的Release我们都需要了解一下 +- 我们需要阅读 1.0 版本的 Release +- 往后每一次大的 Release 我们都需要了解一下 ## 示例 -以Flask为例: +以 Flask 为例: -一、先Clone它。 +一、先 Clone 它。 ![clone-flask.png](./img/clone-flask.png) -二、从Release页面找到它的早期版本: +二、从 Release 页面找到它的早期版本: ![flask.png](./img/flask.png) -三、 从上面拿到它的提交号`8605cc3`,然后checkout到这次提交,查看功能。在这个版本里,一共有六百多行代码 +三、 从上面拿到它的提交号 `8605cc3`,然后 checkout 到这次提交,查看功能。在这个版本里,一共有六百多行代码 ![flask-0.1.png](./img/flask-0.1.png) 还是有点长 -四、我们可以找到它的最早版本: +四、我们可以找到它的最早版本: ![flask-init.png](./img/flask-init.png) -然后查看它的`flask.py`文件,只有简单的三百多行,并且还包含一系列注释: +然后查看它的 `flask.py` 文件,只有简单的三百多行,并且还包含一系列注释: ![flask-init.png](./img/flask-init.png) 五、接着,再回过头去阅读 -- 0.1版本 +- 0.1 版本 - 。。。 -- 最新的0.10.1版本 +- 最新的 0.10.1 版本 -GitHub连击 +GitHub 连击 === -## 100天 +## 100 天 -我也是蛮拼的,虽然我想的只是在GitHub上连击100~200天,然而到了今天也算不错。 +我也是蛮拼的,虽然我想的只是在 GitHub 上连击 100~200 天,然而到了今天也算不错。 ![Longest Streak](./img/longest-streak.png) ``在不停地造轮子的过程中,也不停地造车子。`` -在那篇连续冲击365天的文章出现之前,我们公司的大大([https://github.com/dreamhead](https://github.com/dreamhead))也曾经在公司内部说过,天天commit什么的。当然这不是我的动力,在连击140天之前 +在那篇连续冲击 365 天的文章出现之前,我们公司的大大([https://github.com/dreamhead](https://github.com/dreamhead))也曾经在公司内部说过,天天 commit 什么的。当然这不是我的动力,在连击 140 天之前 -- 给过google的``ngx_speed``、``node-coap``等项目创建过pull request +- 给过 Google 的``ngx_speed``、``node-coap`` 等项目创建过 pull request - 也有``free-programming-books``、``free-programming-books-zh_CN``这样的项目。 -- 当然还有一个连击20天。 +- 当然还有一个连击 20 天。 -对比了一下365天连击的commit,我发现我在total上整整多了近0.5倍。 +对比了一下 365 天连击的 commit,我发现我在 total 上整整多了近 0.5 倍。 ![365 Streak](./img/365-streak.jpg) -同时这似乎也意味着,我每天的commit数与之相比多了很多。 +同时这似乎也意味着,我每天的 commit 数与之相比多了很多。 -在连击20的时候,有这样的问题: *为了commit而commit代码*,最后就放弃了。 +在连击20的时候,有这样的问题:*为了 commit 而 commit 代码*,最后就放弃了。 -而现在是``为了填坑而commit``,为自己挖了太多的想法。 +而现在是``为了填坑而 commit``,为自己挖了太多的想法。 -### 40天的提升 +### 40 天的提升 -当时我需要去印度接受毕业生培训,大概有5周左右,想着总不能空手而归。于是在国庆结束后有了第一次commit,当时旅游归来,想着自己在不同的地方有不同的照片,于是这个repo的名字是 [onmap](https://github.com/phodal/onmap)——将自己的照片显示在地图上的拍摄地点(手机是Lumia 920)。然而,中间因为修改账号的原因,丢失了commit。 +当时我需要去印度接受毕业生培训,大概有 5 周左右,想着总不能空手而归。于是在国庆结束后有了第一次 commit,当时旅游归来,想着自己在不同的地方有不同的照片,于是这个 repo 的名字是 [onmap](https://github.com/phodal/onmap)——将自己的照片显示在地图上的拍摄地点(手机是 Lumia 920)。然而,中间因为修改账号的原因,丢失了 commit。 -再从印度说起,当时主要维护三个repo: +再从印度说起,当时主要维护三个 repo: -- 物联网的CoAP协议 +- 物联网的 CoAP 协议 - [一步步设计物联网系统](https://github.com/phodal/designiot)的电子书 -- 一个Node.js + JS的网站 +- 一个 Node.js + JS 的网站 -说说最后一个,最后一个是练习的项目。因为当时培训比较无聊,业余时间比较多,英语不好,加上听不懂印度人的话。晚上基本上是在住的地方默默地写代码,所以当时的目标有这么几个: +说说最后一个,最后一个是练习的项目。因为当时培训比较无聊,业余时间比较多,英语不好,加上听不懂印度人的话。晚上基本上是在住的地方默默地写代码,所以当时的目标有这么几个: - TDD - 测试覆盖率 - 代码整洁 -这也就是为什么那个repo有这样的一行: +这也就是为什么那个 repo 有这样的一行: ![Repo Status](./img/repo-status.png) -做到98%的覆盖率也算蛮拼的,当然还有Code Climate也达到了4.0,也有了112个commits。因此也带来了一些提高: +做到 98% 的覆盖率也算蛮拼的,当然还有 Code Climate 也达到了 4.0,也有了 112 个 commits。因此也带来了一些提高: -- 提高了代码的质量(code climate比jslint更注重重复代码等等一些bad smell)。 -- 对于Mock、Stub、FakesServer等用法有更好的掌握 -- 可以持续地交付软件(版本管理、自动测试、CI、部署等等) +- 提高了代码的质量(code climate 比 jslint 更注重重复代码等等一些 bad smell)。 +- 对于 Mock、Stub、FakesServer 等用法有更好的掌握 +- 可以持续地交付软件(版本管理、自动测试、CI、部署等等) -### 100天的挑战 +### 100 天的挑战 -(ps:从印度回来之后,由于女朋友在泰国实习,有了更多的时间可以看书、写代码) +(PS:从印度回来之后,由于女朋友在泰国实习,有了更多的时间可以看书、写代码) -有意思的是越到中间的一些时间,commits的次数上去了,除了一些简单的pull request,还有一些新的轮子出现了。 +有意思的是越到中间的一些时间,commits 的次数上去了,除了一些简单的 pull request,还有一些新的轮子出现了。 ![Problem](./img/problem.jpg) -这是上一星期的commits,这也就意味着,在一星期里面,我需要在8个repo里切换。而现在我又有了一个新的idea,这时就发现了一堆的问题: +这是上一星期的 commits,这也就意味着,在一星期里面,我需要在 8 个 repo 里切换。而现在我又有了一个新的 idea,这时就发现了一堆的问题: - - 今天工作在这个repo上,突然发现那个repo上有issue,需要去修复,于是就放下了当前的代码。 - - 在不同的repo间切换容易分散精力 + - 今天工作在这个 repo 上,突然发现那个 repo 上有 issue,需要去修复,于是就放下了当前的代码。 + - 在不同的 repo 间切换容易分散精力 - 很容易就发现有太多的功能可以实现,但是时间是有限的。 - 没有足够的空闲时间,除了周末。 - 希望去寻找那些有兴趣的人,然而却发现原来没有那么多时间去找人。 -### 140天的希冀 +### 140 天的希冀 -在经历了100天之后,似乎整个人都轻松了,毕竟目标是100~200天。似乎到现在,也不会有什么特殊的情怀,除了一些希冀。 +在经历了 100 天之后,似乎整个人都轻松了,毕竟目标是 100~200 天。似乎到现在,也不会有什么特殊的情怀,除了一些希冀。 -当然,对于一个开源项目的作者来说,最好有下面的情况: +当然,对于一个开源项目的作者来说,最好有下面的情况: - 很多人知道了这个项目 - 很多人用它的项目。 - 在某些可以用这个项目快速解决问题的地方提到了这个项目 -- 提了bug、issue、问题。 -- 提了bug,并解决了。(ps:这是最理想的情况) +- 提了 bug、issue、问题。 +- 提了 bug,并解决了。(PS:这是最理想的情况) -## 200天的Showcase +## 200 天的 Showcase -今天是我连续泡在GitHub上的第200天,也是蛮高兴的,终于到达了: +今天是我连续泡在 GitHub 上的第200天,也是蛮高兴的,终于到达了: ![GitHub 200 days](./img/github-200-days.png) -故事的背影是: 去年国庆完后要去印度接受毕业生培训——就是那个神奇的国度。但是在去之前已经在项目待了九个多月,项目上的挑战越来越少,在印度的时间又算是比较多。便给自己设定了一个长期的goal,即100~200天的longest streak。 +故事的背影是:去年国庆完后要去印度接受毕业生培训——就是那个神奇的国度。但是在去之前已经在项目待了九个多月,项目上的挑战越来越少,在印度的时间又算是比较多。便给自己设定了一个长期的 goal,即 100~200 天的 longest streak。 -或许之前你看到过一篇文章[让我们连击](https://github.com/phodal/github-roam/blob/master/chapters/12-streak-your-github.md),那时已然140天,只是还是浑浑噩噩。到了今天,渐渐有了一个更清晰地思路。 +或许之前你看到过一篇文章[让我们连击](https://github.com/phodal/github-roam/blob/master/chapters/12-streak-your-github.md),那时已然 140 天,只是还是浑浑噩噩。到了今天,渐渐有了一个更清晰地思路。 -先让我们来一下ShowCase,然后再然后,下一篇我们再继续。 +先让我们来一下 ShowCase,然后再然后,下一篇我们再继续。 ### 一些项目简述 -上面说到的培训一开始是用Java写的一个网站,有自动测试、CI、CD等等。由于是内部组队培训,代码不能公开等等因素,加之做得无聊。顺手,拿Node.js +RESTify 做了Server,Backbone + RequireJS + jQuery 做了前台的逻辑。于是在那个日子里,也在维护一些旧的repo,如[iot-coap](https://github.com/phodal/iot-coap)、[iot](https://github.com/phodal/iot),前者是我拿到WebStorm开源License的Repo,后者则是毕业设计。 +上面说到的培训一开始是用 Java 写的一个网站,有自动测试、CI、CD 等等。由于是内部组队培训,代码不能公开等等因素,加之做得无聊。顺手,拿 Node.js +RESTify 做了 Server,Backbone + RequireJS + jQuery 做了前台的逻辑。于是在那个日子里,也在维护一些旧的 repo,如 [iot-coap](https://github.com/phodal/iot-coap)、[iot](https://github.com/phodal/iot),前者是我拿到 WebStorm 开源 License 的 Repo,后者则是毕业设计。 -对于这样一个项目也需要有测试、自动化测试、CI等等。CI用的是Travics-CI。总体的技术构架如下: +对于这样一个项目也需要有测试、自动化测试、CI 等等。CI 用的是 Travics-CI。总体的技术构架如下: #### 技术栈 -前台: +前台: - Backbone - RequireJS @@ -3109,11 +3109,11 @@ GitHub连击 - Mustache - Pure CSS -后台: +后台: - RESTify -测试: +测试: - Jasmine - Chai @@ -3121,21 +3121,21 @@ GitHub连击 - Mocha - Jasmine-jQuery -一直写到五星期的培训结束, 只是没有自动部署。想想就觉得可以用github-page的项目多好~~。 +一直写到五星期的培训结束,只是没有自动部署。想想就觉得可以用 github-page 的项目多好~~。 -过程中还有一些有意思的小项目,如: +过程中还有一些有意思的小项目,如: -### google map solr polygon 搜索 +### Google Maps solr polygon 搜索 -[google map solr polygon 搜索](http://www.phodal.com/blog/google-map-width-solr-use-polygon-search/) +[Google Maps solr polygon 搜索](http://www.phodal.com/blog/google-map-width-solr-use-polygon-search/) -![google map solr](./img/solr.png) +![Google Maps solr](./img/solr.png) -代码: [https://github.com/phodal/gmap-solr](https://github.com/phodal/gmap-solr) +代码:[https://github.com/phodal/gmap-solr](https://github.com/phodal/gmap-solr) ### 技能树 -这个可以从两部分说起: +这个可以从两部分说起: #### 重构 Skill Tree @@ -3148,9 +3148,9 @@ GitHub连击 ![Skill Tree](./img/skilltree.jpg) -代码: [https://github.com/phodal/skillock](https://github.com/phodal/skillock) +代码:[https://github.com/phodal/skillock](https://github.com/phodal/skillock) -#### 技能树Sherlock +#### 技能树 Sherlock - D3.js - Dagre-D3.js @@ -3162,7 +3162,7 @@ GitHub连击 ![Sherlock skill tree](./img/sherlock.png) -代码: [https://github.com/phodal/sherlock](https://github.com/phodal/sherlock) +代码:[https://github.com/phodal/sherlock](https://github.com/phodal/sherlock) #### Django Ionic ElasticSearch 地图搜索 @@ -3173,7 +3173,7 @@ GitHub连击 - Ionic - OpenLayers 3 -代码: [https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch) +代码:[https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch) #### 简历生成器 @@ -3185,7 +3185,7 @@ GitHub连击 - RequireJS - Showdown -代码: [https://github.com/phodal/resume](https://github.com/phodal/resume) +代码:[https://github.com/phodal/resume](https://github.com/phodal/resume) #### Nginx 大数据学习 @@ -3196,23 +3196,23 @@ GitHub连击 - Hadoop - Pig -代码: [https://github.com/phodal/learning-data/tree/master/nginx](https://github.com/phodal/learning-data/tree/master/nginx) +代码:[https://github.com/phodal/learning-data/tree/master/nginx](https://github.com/phodal/learning-data/tree/master/nginx) #### 其他 -虽然技术栈上主要集中在Python、JavaScript,当然还有一些Ruby、Pig、Shell、Java的代码,只是我还是习惯用Python和JavaScript。一些用到觉得不错的框架: +虽然技术栈上主要集中在 Python、JavaScript,当然还有一些 Ruby、Pig、Shell、Java 的代码,只是我还是习惯用 Python 和 JavaScript。一些用到觉得不错的框架: -- Ionic: 开始Hybird移动应用。 -- Django: Python Web开发利器。 -- Flask: Python Web开发小刀。 -- RequireJS: 管理js依赖。 -- Backbone: Model + View + Router。 -- Angluar: ...。 -- Knockout: MVV*。 -- React: 据说会火。 -- Cordova: Hybird应用基础。 +- Ionic:开始 Hybird 移动应用。 +- Django:Python Web 开发利器。 +- Flask:Python Web 开发小刀。 +- RequireJS:管理 JS 依赖。 +- Backbone:Model + View + Router。 +- Angluar:...。 +- Knockout:MVV*。 +- React:据说会火。 +- Cordova:Hybird 应用基础。 -还应该有: +还应该有 - ElasticSearch - Solr @@ -3221,33 +3221,33 @@ GitHub连击 - MongoDB - Redis -## 365天 +## 365 天 > 给你一年的时间,你会怎样去提高你的水平??? ![GitHub 365](./img/github-365.jpg) -正值这难得的sick leave(万恶的空气),码文一篇来记念一个过去的366天里。尽管想的是在今年里写一个可持续的开源框架,但是到底这依赖于一个好的idea。在我的[GitHub 孵化器](http://github.com/phodal/ideas) 页面上似乎也没有一个特别让我满意的想法,虽然上面有各种不样有意思的ideas。多数都是在过去的一年是完成的,然而有一些也是还没有做到的。 +正值这难得的 sick leave(万恶的空气),码文一篇来记念一个过去的 366 天里。尽管想的是在今年里写一个可持续的开源框架,但是到底这依赖于一个好的 idea。在我的 [GitHub 孵化器](http://github.com/phodal/ideas) 页面上似乎也没有一个特别让我满意的想法,虽然上面有各种不样有意思的 ideas。多数都是在过去的一年是完成的,然而有一些也是还没有做到的。 -尽管一直在GitHub上连击看上去似乎是没有多大必要的,但是人总得有点追求。如果正是漫无目的,却又想着提高技术的同时,为什么不去试试?毕竟技术非常好、不需要太多练习的人只是少数,似乎这样的人是不存在的。大多数的人都是经过练习之后,才会达到别人口中的“技术好”。 +尽管一直在 GitHub 上连击看上去似乎是没有多大必要的,但是人总得有点追求。如果正是漫无目的,却又想着提高技术的同时,为什么不去试试?毕竟技术非常好、不需要太多练习的人只是少数,似乎这样的人是不存在的。大多数的人都是经过练习之后,才会达到别人口中的“技术好”。 这让我想起了充斥着各种气味的知乎上的一些问题,在一些智商被完虐的话题里,无一不是因为那些人学得比别人早——哪来的天才?所谓的天才,应该是未来的智能生命一般,一出生什么都知道。如果并非如此,那只是说明他练习到位了。 -练习不到位便意味着,即使你练习的时候是一万小时的两倍,那也是无济于事的。如果你学得比别人晚,在**很长的一段时间里**(可能直到进棺材)输给别人是必然的——落后就要挨打。就好像我等毕业于一所二本垫底的学校里,如果在过去我一直保持着和别人(各种重点)一样的学习速度,那么我只能一直是Loser。 +练习不到位便意味着,即使你练习的时候是一万小时的两倍,那也是无济于事的。如果你学得比别人晚,在**很长的一段时间里**(可能直到进棺材)输给别人是必然的——落后就要挨打。就好像我等毕业于一所二本垫底的学校里,如果在过去我一直保持着和别人(各种重点)一样的学习速度,那么我只能一直是 Loser。 -需要注意的是,对你来说考上二本很难,并不是因为你比别人笨。教育资源分配不均的问题,在某种程度上导致了新的阶级制度的出现。如[我的首页](https://www.phodal.com/)说的那样: **THE ONLY FAIR IS NOT FAIR**——唯一公平的是它是不公平的。我们可以做的还有很多——**CREATE & SHARE**。真正的不幸是,因为营养不良导致的教育问题。 +需要注意的是,对你来说考上二本很难,并不是因为你比别人笨。教育资源分配不均的问题,在某种程度上导致了新的阶级制度的出现。如[我的首页](https://www.phodal.com/)说的那样:**THE ONLY FAIR IS NOT FAIR**——唯一公平的是它是不公平的。我们可以做的还有很多——**CREATE & SHARE**。真正的不幸是,因为营养不良导致的教育问题。 -于是在想明白了很多事的时候起,便有了Re-Practise这样的计划,而365天只是中间的一个产物。 +于是在想明白了很多事的时候起,便有了 Re-Practise 这样的计划,而 365 天只是中间的一个产物。 ### 编程的基础能力 -虽说算法很重要,但是编码才是基础能力。算法与编程在某种程度上是不同的领域,算法编程是在编程上面的一级。算法写得再好,如果别人很难直接拿来复用,在别人眼里就是shit。想出能work的代码一件简单的事,学会对其重构,使之变得更易读就是一件有意义的事。 +虽说算法很重要,但是编码才是基础能力。算法与编程在某种程度上是不同的领域,算法编程是在编程上面的一级。算法写得再好,如果别人很难直接拿来复用,在别人眼里就是 shit。想出能 work 的代码一件简单的事,学会对其重构,使之变得更易读就是一件有意义的事。 -于是,在某一时刻在GitHub上创建了一个组织,叫[Artisan Stack](https://github.com/artisanstack)。当时想的是在GitHub寻找一些JavaScript项目,对其代码进行重构。但是到底是影响力不够哈,参与的人数比较少。 +于是,在某一时刻在 GitHub 上创建了一个组织,叫 [Artisan Stack](https://github.com/artisanstack)。当时想的是在 GitHub 寻找一些 JavaScript 项目,对其代码进行重构。但是到底是影响力不够哈,参与的人数比较少。 #### 重构 -如果你懂得如何写出高可读的代码,那么我想你是不需要这个的,但是这意味着你花了更多的时候在思考上了。当谈论重构的时候,让我想起了TDD(测试驱动开发)。即使不是TDD,那么如果你写着测试,那也是可以重构的。(之前写过一些利用Intellij IDEA重构的文章:[提炼函数](https://www.phodal.com/blog/intellij-idea-refactor-extract-method/)、[以查询取代临时变量](https://www.phodal.com/blog/intellij-idea-refactor-replace-temp-with-query/)、[重构与Intellij Idea初探](https://www.phodal.com/blog/thoughtworks-refactor-and-intellij-idea/)、[内联函数](https://www.phodal.com/blog/intellij-idea-refactor-inline-method/)) +如果你懂得如何写出高可读的代码,那么我想你是不需要这个的,但是这意味着你花了更多的时候在思考上了。当谈论重构的时候,让我想起了 TDD(测试驱动开发)。即使不是 TDD,那么如果你写着测试,那也是可以重构的。(之前写过一些利用 Intellij IDEA 重构的文章:[提炼函数](https://www.phodal.com/blog/intellij-idea-refactor-extract-method/)、[以查询取代临时变量](https://www.phodal.com/blog/intellij-idea-refactor-replace-temp-with-query/)、[重构与 Intellij Idea 初探](https://www.phodal.com/blog/thoughtworks-refactor-and-intellij-idea/)、[内联函数](https://www.phodal.com/blog/intellij-idea-refactor-inline-method/)) 在各种各样的文章里,我们看到过一些相关的内容,最好的参考莫过于《重构》一书。最基础不过的原则便是函数名,取名字很难,取别人能读懂的名字更难。其他的便有诸如长函数、过大的类、重复代码等等。在我有限的面试别人的经历里,这些问题都是最常见的。 @@ -3255,58 +3255,58 @@ GitHub连击 而如果没有测试,其他都是扯淡。写好测试很难,写个测试算是一件容易的事。只是有些容易我们会为了测试而测试。 -在我写[EchoesWorks](https://github.com/echoesworks/echoesworks)和[Lan](https://github.com/phodal/lan)的过程中,我尽量去保证足够高的测试覆盖率。 +在我写 [EchoesWorks](https://github.com/echoesworks/echoesworks) 和 [Lan](https://github.com/phodal/lan) 的过程中,我尽量去保证足够高的测试覆盖率。 ![lan](./img/lan.png) ![EchoesWorks](./img/echoesworks.png) -从测试开始的TDD,会保证方法是可测的。从功能到测试则可以提供工作次效率,但是只会让测试成为测试,而不是代码的一部分。 +从测试开始的 TDD,会保证方法是可测的。从功能到测试则可以提供工作次效率,但是只会让测试成为测试,而不是代码的一部分。 -测试是代码的最后一公里。所以,尽可能的为你的GitHub上的项目添加测试。 +测试是代码的最后一公里。所以,尽可能的为你的 GitHub 上的项目添加测试。 #### 编码的过程 -初到TW时,Pair时候总会有人教我如何开始编码,这应该也是一项基础的能力。结合日常,重新演绎一下这个过程: +初到 TW 时,Pair 时候总会有人教我如何开始编码,这应该也是一项基础的能力。结合日常,重新演绎一下这个过程: 1. 有一个可衡量、可实现、过程可测的目标 -2. Tasking (即对要实现的目标过程进行分解) -3. 一步步实现 (如TDD) +2. Tasking(即对要实现的目标过程进行分解) +3. 一步步实现(如 TDD) 4. 实现目标 放到当前的场景就是: -1. 我想在GitHub上连击365天。对应于每一个时候段的目标都应该是可以衡量、测试的——即每天都会有Contributions。 -2. 分解就是一个痛苦的过程。理想情况下,我们应该会有每天提交,但是这取决于你的repo的数量,如果没有新的idea出现,那么这个就变成为了Contributions而Commit。 +1. 我想在 GitHub 上连击 365 天。对应于每一个时候段的目标都应该是可以衡量、测试的——即每天都会有 Contributions。 +2. 分解就是一个痛苦的过程。理想情况下,我们应该会有每天提交,但是这取决于你的 repo 的数量,如果没有新的 idea 出现,那么这个就变成为了 Contributions 而 Commit。 3. 一步步实现 在我们实际工作中也是如此,接到一个任务,然后分解,一步步完成。不过实现会稍微复杂一些,因为事务总会有抢占和优先级的。 ### 技术与框架设计 -在上上一篇博客中《[After 500: 写了第500篇博客,然后呢?](https://www.phodal.com/blog/after-500-blogposts-analytics-after-tech/)》也深刻地讨论了下这个问题,技术向来都是后发者优势。对于技术人员来说,也是如此,后发者占据很大的优势。 +在上上一篇博客中《[After 500:写了第 500 篇博客,然后呢?](https://www.phodal.com/blog/after-500-blogposts-analytics-after-tech/)》也深刻地讨论了下这个问题,技术向来都是后发者优势。对于技术人员来说,也是如此,后发者占据很大的优势。 -如果我们只是单纯地把我们的关注点仅仅放置于技术上,那么我们就不具有任何的优势。而依赖于我们的编程经验,我们可以在特定的时候创造一些框架。而架构的设计本身就是一件有意思的事,大抵是因为程序员都喜欢创造。(ps:之前曾经写过这样一篇文章,《[对不起,我并不热爱编程,我只喜欢创造](https://www.phodal.com/blog/sorry-i-don't-like-programming/)》) +如果我们只是单纯地把我们的关注点仅仅放置于技术上,那么我们就不具有任何的优势。而依赖于我们的编程经验,我们可以在特定的时候创造一些框架。而架构的设计本身就是一件有意思的事,大抵是因为程序员都喜欢创造。(PS:之前曾经写过这样一篇文章,《[对不起,我并不热爱编程,我只喜欢创造](https://www.phodal.com/blog/sorry-i-don't-like-programming/)》) **创造是一种知识的再掌握过程。** -回顾一下写echoesworks的过程,一开始我需要的是一个网页版的PPT,当然这类的东西已经有很多了,如impress.js、bespoke.js等等。分析一下所需要的功能:markdown解析器、键盘事件处理、Ajax、进度条显示、图片处理、Slide。我们可以在GitHub上找到各式各样的模块,我们所要做的就是将之结合在一样。在那之前,我试着用类似的原理写(组合)了[Lettuce](https://github.com/phodal/lettuce)。 +回顾一下写 echoesworks 的过程,一开始我需要的是一个网页版的 PPT,当然这类的东西已经有很多了,如 impress.js、bespoke.js 等等。分析一下所需要的功能:markdown 解析器、键盘事件处理、Ajax、进度条显示、图片处理、Slide。我们可以在 GitHub 上找到各式各样的模块,我们所要做的就是将之结合在一样。在那之前,我试着用类似的原理写(组合)了 [Lettuce](https://github.com/phodal/lettuce)。 组合相比于创造过程是一个更有挑战性的过程,我们需要在这过程去设计胶水来粘合这些代码,并在最终可以让他工作。这好比是我们在平时接触到的任务划分,每个人负责相应的模块,最后整合。 -我在写[lan](https://github.com/phodal/lan)的时候,也是类似的,但是不同的是我已经设计了一个清晰的架构图。 +我在写 [lan](https://github.com/phodal/lan) 的时候,也是类似的,但是不同的是我已经设计了一个清晰的架构图。 ![Lan IoT](./img/lan-iot.jpg) -而在我们实现的编码过程也是如此,使用不同的框架,并且让他们能工作。如早期玩的[moqi.mobi](https://github.com/echoesworks/moqi.mobi),基于Backbone、RequireJS、Underscore、Mustache、Pure CSS。在随后的时间里,用React替换了View层,就有了[backbone-react](https://github.com/phodal/backbone-react)的练习。 +而在我们实现的编码过程也是如此,使用不同的框架,并且让他们能工作。如早期玩的 [moqi.mobi](https://github.com/echoesworks/moqi.mobi),基于 Backbone、RequireJS、Underscore、Mustache、Pure CSS。在随后的时间里,用 React 替换了 View 层,就有了 [backbone-react](https://github.com/phodal/backbone-react) 的练习。 -技术同人一样,需要不断地往高一级前进。我们只需要不断地Re-Practise。 +技术同人一样,需要不断地往高一级前进。我们只需要不断地 Re-Practise。 ### 领域与练习 说业务好像不太适合程序员的口味,那就领域吧。不同行业的人,如百度、阿里、腾讯,他们的领域核心是不一样的。 -而领域本身也是相似的,这可以解释为什么互联网公司都喜欢互相挖人,而一般都不会去华为、中兴等非互联网领域挖人。出了这个领域,你可能连个毕业生都不如。领域、业务同技术一样是不断强化知识的一个过程。Ritchie先实现了BCPL语言,而后设计了C语言,而BCPL语言一开始是基于CPL语言。 +而领域本身也是相似的,这可以解释为什么互联网公司都喜欢互相挖人,而一般都不会去华为、中兴等非互联网领域挖人。出了这个领域,你可能连个毕业生都不如。领域、业务同技术一样是不断强化知识的一个过程。Ritchie 先实现了 BCPL 语言,而后设计了 C 语言,而 BCPL 语言一开始是基于 CPL 语言。 领域本身也在不断进化。 @@ -3314,7 +3314,7 @@ GitHub连击 ### 其他 -是时候写这个小结了。从不会写代码,到写代码是从0到1的过程,但是要从1到60都不是一件容易的事。无论是刷GitHub也好(不要是自动提交),或者是换工作也好,我们都在不断地练习。 +是时候写这个小结了。从不会写代码,到写代码是从 0 到 1 的过程,但是要从 1 到 60 都不是一件容易的事。无论是刷 GitHub 也好(不要是自动提交),或者是换工作也好,我们都在不断地练习。 而练习是要分成不同的几个步骤,不仅仅局限于技术: @@ -3325,28 +3325,28 @@ GitHub连击 --- -## 500天 +## 500 天 -尽管之前已经有100天、200天、365天的文章,但是这不是一篇象征性的500天的文章。对这样的一个事物,每个人都会有不同听看法。有的会说这是一件好事,有的则不是。但是别人的看法终究不重要,因为了解你自己的只有你自己。别人都只是以他们的角度来提出观点。 +尽管之前已经有 100 天、200 天、365 天的文章,但是这不是一篇象征性的 500 天的文章。对这样的一个事物,每个人都会有不同听看法。有的会说这是一件好事,有的则不是。但是别人的看法终究不重要,因为了解你自己的只有你自己。别人都只是以他们的角度来提出观点。 -在这500天里,我发现两点有意思的事,也是总结的时候才意识到的: +在这 500 天里,我发现两点有意思的事,也是总结的时候才意识到的: 1. 编程的情绪周期 2. 有意图的练习 那么,当我们不断地练习的时候,我们就可以写出更好的代码。 -我想你也听过一万小时天才理论的说法:要成为某个领域的专家,需要10000小时。而在这其中每重要的一点是有意图的练习——而不是一直重复性地用不同的语言去写一个相同的算法。如果我们有一天8小时的工作时间 + 2 小时的提高时间,那么我们还是需要1000天才能实现一万小时。 +我想你也听过一万小时天才理论的说法:要成为某个领域的专家,需要 10000 小时。而在这其中最重要的一点是有意图的练习——而不是一直重复性地用不同的语言去写一个相同的算法。如果我们有一天 8 小时的工作时间 + 2 小时的提高时间,那么我们还是需要 1000 天才能实现一万小时。 -### 500天与10000小时 +### 500 天与10000 小时 -当然如果你连做梦也在写代码的话,那么我想500天就够了,哈哈~~。 +当然如果你连做梦也在写代码的话,那么我想 500 天就够了,哈哈~~。 ![Gtihub 500](./img/github-500.jpg) -虽然不是连击次数最多的,但是根据[Most active GitHub users ](http://git.io/top)的结果来说,好似是大陆提交数最多的人,没有之一。再考虑到提交都是有意义的——不是机器刷出来的,不是有意识的去刷,我觉得还是有很大成就感的。 +虽然不是连击次数最多的,但是根据 [Most active GitHub users ](http://git.io/top) 的结果来说,好似是大陆提交数最多的人,没有之一。再考虑到提交都是有意义的——不是机器刷出来的,不是有意识的去刷,我觉得还是有很大成就感的。 -而要实现500天连击很重要的两点是:时间和idea。但是我觉得idea并不是非常重要的,我们可以造轮子,这一点就是在早期我做得最多的一件事,不断地造轮子——如《[造轮子与从Github生成轮子](https://www.phodal.com/blog/create-framework-from-github/)》一文中所说。除此,你还可以用《[GitHub去管理你的idea](https://www.phodal.com/blog/use-github-manage-idea/)》,每当你想到一个Idea以及完成一个idea的时间你就会多一次提交。 +而要实现 500 天连击很重要的两点是:时间和 idea。但是我觉得 idea 并不是非常重要的,我们可以造轮子,这一点就是在早期我做得最多的一件事,不断地造轮子——如《[造轮子与从Github生成轮子](https://www.phodal.com/blog/create-framework-from-github/)》一文中所说。除此,你还可以用《[GitHub去管理你的idea](https://www.phodal.com/blog/use-github-manage-idea/)》,每当你想到一个 Idea 以及完成一个 idea 的时间你就会多一次提交。 时间则是一件很讽刺的事,因为人们要加班。加班的原因,要么是因为工作的内容很有意思,要么是因为钱。如果不是因为钱的话,为什么不去换个工作呢?比如我司。看似两者间存在很多的对立,但是我总在想技术的提升可以在后期解决收入的问题,而不需要靠加班来解决这个问题。人总是要活着的,钱是必需的,但是程序员的收入都不低。 @@ -3405,7 +3405,7 @@ THE ONLY FAIR IS NOT FAIR . ENJOY CREATE & SHARE. 编码是一件值得练习的事,你从书中、互联网上看到的那一个个的编程大牛无一不是从一点点的小技能积累起来的。从小接触可以让你有一个好的开始,一段好好的练习也会帮助你更好的前进。 -记得我在最开始练习的时候,我分几个不同的阶段去练习: +记得我在最开始练习的时候,我分几个不同的阶段去练习: - 按照《重构:改善即有代码的设计》一书边寻找一些 bad smell 的代码,一边想方设法去让代码变得优雅。 - 按照《设计模式》以及《重构与模式》来将代码重构成某种设计模式。 @@ -3432,9 +3432,9 @@ THE ONLY FAIR IS NOT FAIR . ENJOY CREATE & SHARE. 建议试试我们家的Growth哈,地址:http://growth.ren。 -文章的剩下部分就让我分享一下:在这723天里,我创造出了哪些有意思的东西(ps:让我装逼一下)——其实我不仅仅只是 Markdown 写得好 +文章的剩下部分就让我分享一下:在这 723 天里,我创造出了哪些有意思的东西(PS:让我装逼一下)——其实我不仅仅只是 Markdown 写得好 -#### 2014年 +#### 2014 年 时间:2014.10.08-2014.12.30 @@ -3442,18 +3442,18 @@ THE ONLY FAIR IS NOT FAIR . ENJOY CREATE & SHARE. 在这一段时间里,我创建的项目大部分都是一些物联网项目: - - [iot-coap](https://github.com/phodal/iot-coap) 一个基于CoAP协议的物联网 + - [iot-coap](https://github.com/phodal/iot-coap) 一个基于 CoAP 协议的物联网 - [designiot](https://github.com/phodal/designiot) 即电子书《教你设计物联网系统》 - - [iot-document](https://github.com/phodal/awesome-iot-document) 收集一些物联网相关的资料,和Awesome不是一个性质 - - [iot](https://github.com/phodal/iot) 基于PHP框架Laravel的物联网 - - iot-android 一个与iot项目相配套的Android程序 + - [iot-document](https://github.com/phodal/awesome-iot-document) 收集一些物联网相关的资料,和 Awesome 不是一个性质 + - [iot](https://github.com/phodal/iot) 基于 PHP 框架 Laravel 的物联网 + - iot-android 一个与 iot 项目相配套的 Android 程序 - 等等 -正是这几个IoT项目,让Packt出版社找到了我,才有了后来和国内外出版社打交道的故事。也开始了技术审阅、翻译、写书的各种故事,想想就觉得这个开头真的很好。 +正是这几个 IoT 项目,让 Packt 出版社找到了我,才有了后来和国内外出版社打交道的故事。也开始了技术审阅、翻译、写书的各种故事,想想就觉得这个开头真的很好。 -期间还创建了一个很有意思的Chrome插件,叫onebuttonapp——没错,就是模仿Amazon的一键下单写的。这个插件的目的就是难证当时在项目上用的Backbone、Require.js的这一套可以在插件上好好玩。 +期间还创建了一个很有意思的 Chrome 插件,叫 onebuttonapp——没错,就是模仿 Amazon 的一键下单写的。这个插件的目的就是难证当时在项目上用的 Backbone、Require.js 的这一套可以在插件上好好玩。 -OnMap项目是为了让我用Nokia Lumia 920拍照的照片,可以在地图上显示而创建的项目。 +OnMap 项目是为了让我用 Nokia Lumia 920 拍照的照片,可以在地图上显示而创建的项目。 当然还有其他的一些小项目啦。 @@ -3463,49 +3463,49 @@ OnMap项目是为了让我用Nokia Lumia 920拍照的照片,可以在地图上 整个区间就是刷各种前端的技术栈,创建了各种有意思的项目: - - [Lettuce框架](https://github.com/phodal/lettuce),一个基于简单的SPA框架 - - [echoesworks](https://github.com/phodal/echoesworks),一个支持字幕、Markdown、动画的Slide框架 - - [diaonan](https://github.com/phodal/diaonan),一个支持CoAP、MQTT、HTTP的物联网项目 + - [Lettuce框架](https://github.com/phodal/lettuce),一个基于简单的 SPA 框架 + - [echoesworks](https://github.com/phodal/echoesworks),一个支持字幕、Markdown、动画的 Slide 框架 + - [diaonan](https://github.com/phodal/diaonan),一个支持 CoAP、MQTT、HTTP 的物联网项目 - [developer](https://github.com/phodal/developer),收集各种 Web Developer 成长路线,以及读书图谱 期间还创建了几个混合应用项目: - - [learning-ionic](https://github.com/phodal/learning-ionic),程序语言答人,各种hello,world的小应用 + - [learning-ionic](https://github.com/phodal/learning-ionic),程序语言答人,各种 hello, world 的小应用 - [ionic-elasticsearch](https://github.com/phodal/ionic-elasticsearch), Django ElasticSearch Ionic 打造 GIS 移动应用 - - [designiot-app](https://github.com/phodal/designiot-app),教你设计物联网APP版 + - [designiot-app](https://github.com/phodal/designiot-app),教你设计物联网 App 版 -更多内容可以见我的Idea列表:[https://github.com/phodal/ideas](https://github.com/phodal/ideas),我实在是不想写了。 +更多内容可以见我的 Idea 列表:[https://github.com/phodal/ideas](https://github.com/phodal/ideas),我实在是不想写了。 -#### 2016年 +#### 2016 年 ![2016.png](./img/2016.png) -我们有了Growth系列的电子书、APP,还有Mole,几个极具代表性的项目就够了。 +我们有了 Growth 系列的电子书、App,还有 Mole,几个极具代表性的项目就够了。 - - [Growth](https://github.com/phodal/growth),一款专注于Web开发者成长的应用,涵盖Web开发的流程及技术栈,Web开发的学习路线、成长衡量等各方面。 - - [Growth: 全栈增长工程师指南](https://github.com/phodal/growth-ebook),一本关于如何成为全栈增长工程师的指南 - - [Growth: 全栈增长工程师实战](https://github.com/phodal/growth-in-action),在Growth中我们介绍的只是一系列的实践,而Growth实战则会带领读者去履行这些实践 + - [Growth](https://github.com/phodal/growth),一款专注于 Web 开发者成长的应用,涵盖 Web 开发的流程及技术栈,Web 开发的学习路线、成长衡量等各方面。 + - [Growth:全栈增长工程师指南](https://github.com/phodal/growth-ebook),一本关于如何成为全栈增长工程师的指南 + - [Growth:全栈增长工程师实战](https://github.com/phodal/growth-in-action),在 Growth 中我们介绍的只是一系列的实践,而 Growth 实战则会带领读者去履行这些实践 ### See you Again 停止这次连击,只是为了有一个更好的开始。 -如果你也想提高自己,不妨从创建你的 ideas 项目开始,如我的[Ideas](https://github.com/phodal/ideas)项目一样,上面已经有了大量的 Idea。然后,我们还可以依据这一个个的项目,创建出一本电子书,即 [ideabook](https://github.com/phodal/ideabook)。 +如果你也想提高自己,不妨从创建你的 ideas 项目开始,如我的 [Ideas](https://github.com/phodal/ideas) 项目一样,上面已经有了大量的 Idea。然后,我们还可以依据这一个个的项目,创建出一本电子书,即 [ideabook](https://github.com/phodal/ideabook)。 GitHub 里程碑 === -写在GitHub 的第 19999 个 star 时 +写在 GitHub 的第 19999 个 Star 时 --- > Star 虽好,可不要贪杯哦。 > 两年前在做 Annual Review 订下一年的目标时,想着写一个开源框架。去年订下今年的目标时,仍然继续着这样的想法。今年又要制定下一年的目标,2333~~。 -不久前,在 GitHub Ranking 上看到自己的 star 数(star 不是设计用于做“点赞”的,而是用来收藏的)时,发现已经快 20000 了。然后把自己的项目过了一遍,发现没有一个比较好的**代表性框架**,要么是应用,要么是电子书。 +不久前,在 GitHub Ranking 上看到自己的 Star 数(Star 不是设计用于做“点赞”的,而是用来收藏的)时,发现已经快 20000 了。然后把自己的项目过了一遍,发现没有一个比较好的**代表性框架**,要么是应用,要么是电子书。 -前 8 个项目里,除了 Growth 应用以外,其他的都是电子书内容——六本电子书加起来的 star 数有 **10619**,果然是骗 star 的。我只能尽力地去想想:为什么事情会变成这样了? +前 8 个项目里,除了 Growth 应用以外,其他的都是电子书内容——六本电子书加起来的 Star 数有 **10619**,果然是骗 Star 的。我只能尽力地去想想:为什么事情会变成这样了? ### 从创建开源框架说起 @@ -3515,7 +3515,7 @@ GitHub 里程碑 当时,我遇到的最主要的问题是:**想参与到项目的人并没有遇到足够的能力**。你还需要花费大量的时间去教他们,鼓励 GitHub 新手并不是一件容易的事。有时我需要在接受他的 PR 后,再修改他的代码。并且人们提交 PR 可能是出于不同的原因。 -然后,知道了开源世界还有一个游戏规则是:**谁的影响力大,谁就能产生更广泛的影响**。如 Virtual Dom 并不是 Facebook 首创的,但是却因为 FB 火的; 松本行弘在写下 mruby 的 README 时(印象中是这个项目),star 数就已经过 1k 了。这种例子数不胜数,要么是在推广上花了力气,要么个人、公司有着更大的影响力。 +然后,知道了开源世界还有一个游戏规则是:**谁的影响力大,谁就能产生更广泛的影响**。如 Virtual Dom 并不是 Facebook 首创的,但是却因为 FB 火的; 松本行弘在写下 mruby 的 README 时(印象中是这个项目),Star 数就已经过 1k 了。这种例子数不胜数,要么是在推广上花了力气,要么个人、公司有着更大的影响力。 一年前,稍微改变了下策略:暂时以**培养人为主**,同时想着做一个合适的开源框架——只是在今年看来,前端领域已经没有合适的地方可以造轮子了。 @@ -3585,7 +3585,7 @@ GitHub 里程碑 练习新的框架,我总习惯于,**编写一系列相关的 DEMO 项目,然后使用 awesome-xxx 探索可能性。** -Awesome-xxx 系列,是 GitHub 上最容易赚 star 的类型。但凡是有一定知识度的领域、语言、框架等,都有自己的 awesome-xxx 系列的项目,如 awesome-python, awesome-iot, awesome-react 等等。在这样的项目里,都以一定的知识体系整理出来的,从索引和查阅上相应的方便。如果你想进入一个新的领域,会尝试新的东西就搜索 ``awesome xxx`` 吧。 +Awesome-xxx 系列,是 GitHub 上最容易赚 Star 的类型。但凡是有一定知识度的领域、语言、框架等,都有自己的 awesome-xxx 系列的项目,如 awesome-python, awesome-iot, awesome-react 等等。在这样的项目里,都以一定的知识体系整理出来的,从索引和查阅上相应的方便。如果你想进入一个新的领域,会尝试新的东西就搜索 ``awesome xxx`` 吧。 **温馨提醒**:awesome-xxx 只意味着它们包含尽可能多的资料,并不代表它们拥有所有相关的库。 @@ -3640,39 +3640,39 @@ GitHub 上有太多这样的东西,尽管我没有能赶上个好时候,找 试试你的 GitHub 搜索功能吧。 -# GitHub 获 star 指南 +# GitHub 获 Star 指南 > 每天打开 GitHub Trending,都是各种面试指南,这样的生活真难受。如果你的项目是金子,那么请读读这篇文章。 -GitHub 是一个非常有意思的地方,也常常变得非常有争议。有证据表明,GitHub 在某种程度上已经成为了简历的一部分。所谓的证据,便是培训班的人在帮助面试者美化 GitHub 页面——从 Vue 高仿各类项目,到淘宝买 star 来粉饰门面。作为一个面试官,我向来是非常讨厌这样的行为。那么作为一个正直的开发人员,他/她们也越来越需要通过 GitHub 去证明自己的能力。否则,总有一天**劣币驱逐良币**,导致 GitHub Trending 上的项目越来越不堪入目。 +GitHub 是一个非常有意思的地方,也常常变得非常有争议。有证据表明,GitHub 在某种程度上已经成为了简历的一部分。所谓的证据,便是培训班的人在帮助面试者美化 GitHub 页面——从 Vue 高仿各类项目,到淘宝买 Star 来粉饰门面。作为一个面试官,我向来是非常讨厌这样的行为。那么作为一个正直的开发人员,他/她们也越来越需要通过 GitHub 去证明自己的能力。否则,总有一天**劣币驱逐良币**,导致 GitHub Trending 上的项目越来越不堪入目。 出于这样的目的,我想为那些有真金白银的小伙伴写一篇攻略。至于其他/她人的看法倒是不重要,帮助那些金子从水底浮出来,才是我们应该做的。要是有太多的过于水的项目,每天打开 GitHub Trending,都是各种面试指南,那生活还叫生活吗?那叫被面试强迫的生活。 -## 为什么我们 star 一个项目 +## 为什么我们 Star 一个项目 在 GitHub 获得 Star 的重点是,**碰触人们的 G 点**——人们只对和自己有关的事情感兴趣。或是证明自己是对这个感兴趣,或是觉得这个项目不错可以收藏,或者是觉得作者不容易鼓励一下作者。 -当然了,我痛恨那些,投机取巧的人——在 GitHub 放置大量非自己创作的电子书、学术资料、课程,以获取 star。 +当然了,我痛恨那些,投机取巧的人——在 GitHub 放置大量非自己创作的电子书、学术资料、课程,以获取 Star。 获得 Star 的核心是:**你有人们想要的东西,你分享了人们想要的内容**。这些内容可以是代码、文档、文章、资料、指南,只要它能帮助到其他/她人,那么它便是有价值的。当然了作为 GitHub 本身来说,那些通过 Git 和版本管理可以控制的内容,才更适合于这个平台上。 所以,当你手上拥有了人们想要的东西时,那么你就可以使用这份指南,来帮助你构建出更成功的项目。 -## 我的获 star 方式 +## 我的获 Star 方式 -作为一个 GitHub 上的“大 V”,我往往不需要花费太多的精力在项目宣传上。在 GitHub 上创建一个项目,然后 star 就来了……。有时候会比较“无耻”,等到某个项目做得稳定的时候,再给自己一个 star ,吸引更多的吃瓜群众。而后,写一系列的文章来介绍自己的项目。唉,做个开源项目不容易啊。 +作为一个 GitHub 上的“大 V”,我往往不需要花费太多的精力在项目宣传上。在 GitHub 上创建一个项目,然后 Star 就来了……。有时候会比较“无耻”,等到某个项目做得稳定的时候,再给自己一个 Star ,吸引更多的吃瓜群众。而后,写一系列的文章来介绍自己的项目。唉,做个开源项目不容易啊。 但是这些并不管用,因为有时候,我写的代码是大家丝毫不感兴趣的内容。如我最近写的 Serverless 密码管理器 MoPass:我在公众号上、博客上、知乎上写了文章来宣传这个项目,最后只吸引了一小部分人的注意——<= 25。毕竟,你觉得好的东西,那只是对你来说有用。对于其他/她人来说,这个密码管理器可能远远不如 1Password。 -再举个成功的例子,最近我在思考:**新项目的检查清单**,即当我们来到或者开始一个项目的时候,我们需要做哪些事情,对应的还需要考虑什么因素。于是我在 GitHub 上创建了一个名为 New Project Checklist ([https://github.com/phodal/new-project-checklist](https://github.com/phodal/new-project-checklist) ) 的项目。我只是按自己的想法,在 README 上写下了要考虑的中英文因素,还没编写 Web 部分,就已经获得了 100+ 的 star。与此同时,因为 Web 部分还没完成,所以我还没在我的博客、专栏上进行宣传。 +再举个成功的例子,最近我在思考:**新项目的检查清单**,即当我们来到或者开始一个项目的时候,我们需要做哪些事情,对应的还需要考虑什么因素。于是我在 GitHub 上创建了一个名为 New Project Checklist ([https://github.com/phodal/new-project-checklist](https://github.com/phodal/new-project-checklist) ) 的项目。我只是按自己的想法,在 README 上写下了要考虑的中英文因素,还没编写 Web 部分,就已经获得了 100+ 的 Star。与此同时,因为 Web 部分还没完成,所以我还没在我的博客、专栏上进行宣传。 -我只是写了一个 README,然后 star 就来了。但是,一般情况下,我们需要怎么做呢? +我只是写了一个 README,然后 Star 就来了。但是,一般情况下,我们需要怎么做呢? ## GitHub 流量分析 -实际上,当我们在说获得 star 的时候,我们说的是**为自己的项目做推广**。只是呢,获得 star 是其中的一个结果产物,也就是说,我们在宣传项目的过程中,获得了关注度。至于推广本身来说,不同的人会有不同的看法。 +实际上,当我们在说获得 Star 的时候,我们说的是**为自己的项目做推广**。只是呢,获得 Star 是其中的一个结果产物,也就是说,我们在宣传项目的过程中,获得了关注度。至于推广本身来说,不同的人会有不同的看法。 -事实上,GitHub 获取 star 与我们日常了解的营销差不多,先将用户吸引到我们的 GitHub 页面,再让用户有关注的动力(这一点太难了)。 +事实上,GitHub 获取 Star 与我们日常了解的营销差不多,先将用户吸引到我们的 GitHub 页面,再让用户有关注的动力(这一点太难了)。 因此开始之前,我们先看张图就能知道怎么获取流量。如下是《GitHub 漫游指南》最近两周内的流量来源统计(GitHub 通过 Google Analysis 来统计): @@ -3686,7 +3686,7 @@ GitHub 是一个非常有意思的地方,也常常变得非常有争议。有 - 来自于 GitHub Pages 的访问 - 来自其它社交网站的访问 -总的来说,在这一周里,累计有 1,266 次访问,其中有 735 个独立访客。看这数据不错,而实际上 star 率 就有点低。根据 Star History 网站(https://star-history.t9t.io ) 的统计,在过去的近两个月里,才涨了 38 个 star。 +总的来说,在这一周里,累计有 1,266 次访问,其中有 735 个独立访客。看这数据不错,而实际上 Star 率 就有点低。根据 Star History 网站(https://star-history.t9t.io ) 的统计,在过去的近两个月里,才涨了 38 个 Star。 ![GitHub 漫游指南 Star 历史](./img/github-star-history.png) @@ -3695,19 +3695,19 @@ GitHub 是一个非常有意思的地方,也常常变得非常有争议。有 1. 用户看的都是 GitHub Pages 上的内容 2. 从数量上来看,受众并不多 -而我最近在玩的 New Project Checklist ([https://github.com/phodal/new-project-checklist](https://github.com/phodal/new-project-checklist) 的转化率看上去,还算可以: +而我最近在玩的 New Project Checklist([https://github.com/phodal/new-project-checklist](https://github.com/phodal/new-project-checklist) 的转化率看上去,还算可以: ![GitHub New Project Checklist](./img/github-new-project-checklist.png) -在 999 个独立访客里,获得了 202 个 star,转化率差不多是 20%——大家真的对这个项目感兴趣。 +在 999 个独立访客里,获得了 202 个 Star,转化率差不多是 20%——大家真的对这个项目感兴趣。 所以,让我们再强调一下核心的部分:**你分享了人们想要的代码、内容**。否则,你带来了大量的流量,并不一定能转化为你想要的关注度。 -## GitHub 获 star 指南技巧 +## GitHub 获 Star 指南技巧 对于一个创造而言,自然而然的希望自己的项目能有人用。可能一点点的吐槽,都能帮助项目以更好的方式前进。这也就是我为自己项目宣传的意义,在创建项目的时候,我们往往只会按照自己的需要来创建项目。而非其他/她人的需求。因此当有一些新的需求出现时,可能会稍微地影响项目演进的方向。这些方向有好有坏,有时候反而会对自己更有帮助。 -好了,回到我们的正题上,怎么去获取 star? +好了,回到我们的正题上,怎么去获取 Star? ### 技巧一:结合 SEO 技巧 @@ -3778,20 +3778,25 @@ GitHub 是一个人的简历,**而开源项目的 README,就好像是一个 ### 不是技巧的技巧:持续性 -事实上,如你所知,我在 GitHub 上获得大量 star 的原因,并不是说我有一个优秀的项目。而在于我在持续的更新,持续不断地在 GitHub 上做自己喜欢的项目,投入时间分享相关的技巧,还有一系列相关的开源项目。 +事实上,如你所知,我在 GitHub 上获得大量 Star 的原因,并不是说我有一个优秀的项目。而在于我在持续的更新,持续不断地在 GitHub 上做自己喜欢的项目,投入时间分享相关的技巧,还有一系列相关的开源项目。 我们一直在持续变好,打造一个自由的互联网世界,打造一个个自己喜欢的工具。 我们是极客,我们热爱编程,我们热爱分享。 +# GitHub 上有趣的故事 + +1. [Remove my password from lists so hackers won't be able to hack me](https://github.com/danielmiessler/SecLists/pull/155) + + FAQ === -## 如何看待github 项目刷Star行为? +## 如何看待 GitHub 项目刷 Star 行为? -我觉得:在作者开源了源码的情况下,求 star 并没有任何问题。 +我觉得:在作者开源了源码的情况下,求 Star 并没有任何问题。 -开源软件的源头是自由软件,而 RMS 创建自由软件的目的是,反对专利软件,即私有化的软件。如果一个开源项目,要你 star 了,才公开源码,这才叫违反。 +开源软件的源头是自由软件,而 RMS 创建自由软件的目的是,反对专利软件,即私有化的软件。如果一个开源项目,要你 Star 了,才公开源码,这才叫违反。 开源一个软件,并不意味着:你不能用这个开源软件追求任何利益。在所谓的开源运动里,一个开源软件是可以用来卖钱的。可在国内,这是很难的,大公司 如腾讯,可以轻轻松松地用你的软件,而不遵循 GPL 协议。 @@ -3799,8 +3804,8 @@ FAQ 并且对于大部分的开源软件作者来说,都不大可能像 OpenResty、Vue、emqtt 等软件的作者一样,可以从开源软件获得收益来支撑他们开发。还有一些少数人,还能从开源软件中获得一些利益,提高他们今年的 KPI。然后明年的工资,又会多涨一点点。 -可多数人,并没有这样的可能性。我在 GitHub 上有接近 30k 的 star(笑,有接近 20k 是属于电子书的,毕竟思想改变世界),它一点儿也不影响我涨工资。反而多了一个 GitHub “网红” 的称号,要知道在技术领域,“网红” 并不是一个好词。我观察过的大量开源爱好者,怕是比我还惨一些。明明做了很好的工作,因为宣传工作没有做好,连几个 star 都没有,后来就弃坑了。 +可多数人,并没有这样的可能性。我在 GitHub 上有接近 30k 的 Star(笑,有接近 20k 是属于电子书的,毕竟思想改变世界),它一点儿也不影响我涨工资。反而多了一个 GitHub “网红” 的称号,要知道在技术领域,“网红” 并不是一个好词。我观察过的大量开源爱好者,怕是比我还惨一些。明明做了很好的工作,因为宣传工作没有做好,连几个 Star 都没有,后来就弃坑了。 -在这个时候,求 star 就是让心里好受一些,『我做了这么多的事情,我希望得到一些认同』。如果我在一个微信群里,看了作者做了大量的提交,花费了一些心思。在这个时候,我是会去为作者点 star 的。因为我的 GitHub 上粉丝比较多,所以往往会多带来几个 star。 +在这个时候,求 Star 就是让心里好受一些,『我做了这么多的事情,我希望得到一些认同』。如果我在一个微信群里,看了作者做了大量的提交,花费了一些心思。在这个时候,我是会去为作者点 Star 的。因为我的 GitHub 上粉丝比较多,所以往往会多带来几个 Star。 -如果一个人在开源世界里,做了很多事情,连一个 star 都没有。那么,他/她可能就会离开开源世界。当这种事情发生多了,那么开源世界的人就变少了。任何做开源工作的人,都是值得鼓励的——不论他们是出于什么目的。 +如果一个人在开源世界里,做了很多事情,连一个 Star 都没有。那么,他/她可能就会离开开源世界。当这种事情发生多了,那么开源世界的人就变少了。任何做开源工作的人,都是值得鼓励的——不论他们是出于什么目的。 diff --git a/index.html b/index.html index 61c8a19..e5cd71c 100644 --- a/index.html +++ b/index.html @@ -12,9 +12,9 @@ div.column{display: inline-block; vertical-align: top; width: 50%;}