基于underscore和jQuery的微型告警系统

一个监控系统 我们今天要使用underscore.js和jQuery来构建一个客户端的应用,这个应用是一个监控系统的前端,设计师已经给出了界面设计: 而对应的服务器端的API也已经就绪了: $ curl http://localhost:9527/alarms.json -s | jq . 会看到诸如这样的返回值: [ { "proiority": "critical", "occurrence": "2/12/2015 01:23 AM", "summary": "heartbeat failure", "node": "VIQ002" }, { "proiority": "major", "occurrence": "2/12/2015 01:22 AM", "summary": "packages are rejected", "node": "VIQ002" }, { "proiority": "medium", "occurrence": "2/11/2015 01:23 AM", "summary": "connection cannot be established", "node": "VIQ002" } ] 每条告警信息都包含:优先级,发生时间,描述信息,以及发生告警的节点名称。 我们要将这些信息整合,并展示在页面上。 mockup 我在《3周3页面》中讨论过现代前端开发的方式,你也可以参考这篇文章以及这篇文章。我们这里还是采用相同的方式来实现这个mockup,也就是静态页面。 首先我们在index.html中编写HTML: <div class="container"> <h1>Active Event List in transmission</h1> <ul class="events"> <li> <div class="event critical"> <h3>heartbeat failure @ VIQ002</h3> <span class="date">2/12/2015 01:23 AM</span> </div> </li> <li> <div class="event major"> <h3>packages are rejected</h3> <span class="date">2/12/2015 01:23 AM</span> </div> </li> <li> <div class="event medium"> <h3>connection cannot be established</h3> <span class="date">2/12/2015 01:23 AM</span> </div> </li> <!...

February 21, 2015 3 min

略论函数式编程

JavaScript中的map/reduce 在过去的10年间,不论你是否对大数据有所涉足,你肯定听过map/reduce这个貌似很高大上的词。这个高大上的词事实上来自于函数式编程世界。map的意思是影射,即将一个集合中的内容,通过应用某种函数,形成另外一个集合。reduce表示求和,或者规约,即将一个集合以某种函数规约为一个值。 underscore.js是一个非常强大的JavaScript库,也是我的工具箱里的必备品。事实上在我自己的小项目中,我更倾向于使用jQuery+underscore.js来完成所有的功能,而不是使用诸如AngularJS之类的框架。 作为一个库,underscore.js提供了丰富的API来操作JavaScript中的集合,对象,函数等,可以节省程序员大量的时间,我们在这篇文章中来看看underscore.js中基本的函数式编程特性。 使用map消除for-loop 我们先来看一个小例子:我们要编写一个名为makeQuery的函数,它接受一个JavaScript对象和一个分隔符,然后将JavaScript对象展开,形成key=value[分隔符key=value]的形式。正如下面这个测试所反映的: it("make query from object", function() { var cookies = { "JSESSIONID": "6C729E682C05AA56017E3D1675CE8E5F", "_USER": "GEO-NASTAR" }; var expected = "JSESSIONID=6C729E682C05AA56017E3D1675CE8E5F;_USER=GEO-NASTAR"; expect(makeQuery(cookies, ";")).toEqual(expected); }); 一个直接的解决方案是: function makeQuery(obj, delimiter) { var strArray = []; for (var key in obj) { strArray.push(key + "=" + obj[key]); } return strArray.join(delimiter); } 我们再来看另外一个小例子:给定一个字符串(人名)数组,将数组中的所有人名都变成大写字母开头。正如下面这个测试所反映: it("capitalize", function() { var names = ["juanchen", "mingliang", "lu", "juntao"]; var expected = ["Juanchen", "Mingliang", "Lu", "Juntao"]; expect(capitalize(names))....

February 20, 2015 3 min

制作一个多彩的svn diff脚本

Code Review 在ThoughtWorks,我们几乎每天都会进行一个叫code review或者code diff的活动:每天下午5:00,团队成员围坐在一起,将今天的修改大概过一下,这样做的好处非常明显: 分享业务知识,了解彼此的工作 分享技术细节,比如有人使用了某种设计模式 帮助别人发现问题,比如逻辑错误等,群策群力 经过实践,code reivew可以快速发现问题,而且可以尽可能多的分享知识,是一种ThoughtWorker们喜闻乐见的学习/娱乐形式。 但是随着项目的不同,各个团队使用的版本管理工具都不一样。用惯了git的非常漂亮的diff子命令之后,svn的diff简直就是战五渣。没有高亮,没有进度条,就是黑底白字的一些文本,实在无法让人提起兴趣。 这篇文章分享一个简单的方法,可以让你很容易的把svn的diff打造成一个漂亮的工具: diff格式 Diff是一种通用的表示文本差异的格式,细节可以看我之前写过一篇关于diff和patch的文章。需要说明的是,它作为一种标准格式,很多编辑器都提供对这种格式的高亮显示,比如现在非常流行的Sublime Text编辑器: 默认的,svn的diff命令会生成这样朴素的输出: 命令行的diff高亮显示 在Mac下,可以通过brew来安装一个命令行工具,这个工具可以将Diff格式高亮显示: $ brew install colordiff 有了这个工具,就可以将svn生成的Diff格式高亮显示出来: $ svn diff | colordiff 但是你可能已经发现这些神奇的^M,这是Windows系统中的换行符在Unix类系统中的展示,我们需要将Diff先转换一次: $ svn diff | dos2unix | colordiff 如果你的系统中没有dos2unix,可以用brew来安装: $ brew install dos2unix unix2dos 分页器 *nix系统下有两种分页器:more和less,less比more的功能更丰富。less有很多的参数,我们这里选用了3个常见的: -s: 压缩连续的空白行为一行 -M: 给出更多的提示信息,包含行号,百分比等 +Gg: 先跳至要查看文件的末尾,再跳至文件开头,这样从less就可以得到整个流的长度,从而计算出正确的百分比。当然如果是单独文件时,less是明确知道文件长度的,但是如果是从流中重定向过来的文本,less无法在开始时就得知长度。 下面这条命令可以将当前目录下的所有html文件分屏显示,并且在每一屏的最后一行显示百分比等信息: $ cat *.html | less -s -M +Gg 放在一起 好了,我们将每个部分都已经讲解了一遍了,现在让我们将这些零件串起来,在svn的working copy中执行这条命令就可以得到非常漂亮的,分页显示的Diff: $ svn diff | dos2unix | colordiff | less -s -M +Gg 当然,还可以用一个alias(别名)来节省敲入的字符数:...

February 18, 2015 1 min

Linux命令行中的7个小技巧

Linux命令行中的7个小技巧 命令行是开发者的好朋友,*nix系统(包括Mac OS X和各种Linux)都自带了强大的Shell环境,作为一个专业的程序员,Shell是离不开的。这里总结了几个常用的小技巧,都是我自己平时经常用,而又不想每次都去Google的。 如何知道哪个进程在监听4000端口? 当启动服务时,经常会遇到想要Address already in use这样的异常,那么如何知道是哪个进程占用了该端口呢? $ lsof -i :4000 lsof会列出系统目前打开的文件(List open files,Linux世界中,一切都是文件),-i表示网络地址(Internet address),注意此处的冒号。如果不带参数,lsof会列出所有打开的网络地址: $ lsof -i :4000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 32303 jtqiu 7u IPv4 0x947b402a4bb8370b 0t0 TCP *:terabase (LISTEN) Shell中如何设置代理? 很多公司都会有一个代理服务器供员工上外网使用,命令行中设置代理非常容易: export http_proxy="http://username:password@hosename:port" 如果密码中有特设字符,比如$的话,需要转义一下。使用URLEncoding即可,比如$就是%24。最简单的就是在Chrome的Console中输入encodeURIComponent("$")来获得转义字符。 如果不想对某些地址使用代理,可以设置no_proxy环境变量: export no_proxy="127.0.0.1, localhost, *.cnn.com, 192.168.1.10, domain.com:8080" 如何为svn中的脚本设置可执行属性 你在Linux下创建了一个可执行脚本e2e_test.sh,但是团队里的其他人工作在Windows系统上,当你提交可执行脚本之后,他们checkout的是一个不能执行的文件!(其实也在情理之中,Windows这种垃圾货什么时候正常过呢?) 这时候可以通过给这个脚本设置一个svn的属性: svn propset svn:executable "*" e2e_test.sh 这样在Windows上才heckout之后就正常了。 在Bash脚本中如何判断一个文件是否可执行? 有时候我们在Bash中需要判断某个文件是否可以执行,这行脚本可以解救你: if [ -x $FILENAME ]; then # the file is executable fi 判断某个文件是否存在的脚本为:...

February 14, 2015 2 min

在Thoughtworks我们如何做培训

ThoughtWorks内部培训 对新人的培训是每个企业都绕不开的一个话题,企业当然想要每个新人都能直接独当一面,最好可以直接上项目贡献自己的价值。但是从经验来看,所有新人到一个新环境都需要学习很多不同的新东西(新技术,框架,语言,工作方式等等),而每个企业对于培训新人都有各种各样的策略,比如老人带新人,比如扔到项目上让新人自己学。 在ThoughtWorks,我们有着丰富的培训方式,有面向社招的,有面向毕业生的,有民间自发的,有官方组织的,有内部的,也有面向社区的。 TWU TWU全称ThoughtWorks University,面向毕业生,入职之后的第一堂课。TWU的地点设在印度,之前在班加罗尔,后来改到了普内。每一期5周,学生们需要和和全球其他国家地区的同学一起,一般会尽量将各个地区的学生打乱安排,尽量让学生体会多元化的文化,培训内容设计公司文化,软件开发方法论,敏捷开发(Project SImulation)实践等,同时还需要保证学生有足够的代码练习机会。 我在2013年作为讲师参加了一起TWU,对我自己的帮助也非常大,在和来自不同地区的讲师一起备课,学习中学习到了很多的东西,之前似是而非的一些概念也得到了纠正。 TWI TWI全称ThoughtWorks Immersion,面向有经验的社招同事,主要涉及的内容为公司文化(合作,沟通),专业服务(如何专业的解决客户的问题),软件开发流程,敏捷开发方法论等。 我在2012年时参加过TWI,并整理了几篇相关文章,可以参考这里,这里还有这里。 Session Office局限在ThoughtWorks办公室之内,内容随意,参加不参加随意,可以随时加入或随时离开。虽然内容没有限制,但是大多数时候分享的都是技术主题。比如自动化部署,自动测试,Spring 4,Ruby中的构建工具等等。 Sessoin的形式是主讲者找一个自己感兴趣的主题,一个人讲,其他参与者听,鼓励互动。时间一般控制在一个小时以内,所以一般选择在中午饭的时候,有的session会给大家订饭,一边吃一边听。 虽然大部分Sessoin的主题是技术相关的,但是并不局限于此。比如旅游见闻,历史,财务,摄影等等,都可以分享,有时候这些趣味性的Session的参与者更多。 WorkShop Office之内,内容随意,以动手为主,讲解为辅。 HTML/CSS Testable JavaScript 设计工作坊 OO BootCamp Ruby BootCamp 一般来说,Workshop都会组成一个系列,通常会占用几天到几周不等。参与者需要带上电脑,在课堂上进行练习之外,课后还会有一些练习。 3周3页面和可测试的JavaScript是我去年做的两个Workshop。由于Workshop会在下班后或者中午的休息时间,公司会为每个参与者订饭,以节省时间。 郑大晔校 面向刚刚得到offer的毕业生,在上项目之前,我们希望学生的基本技术达到特定的水平,因此设置了一系列的练习。包括 编程基础 开发流程 工作方式 公司文化 等等。郑大晔校的周期为每周一次,一次一天。涉及的内容会与大多数项目上的要求一致,比如西安office的Java/Ruby项目居多,我们的课程安排就会涉及到Java/Ruby方面。当然,各种软技能如工作方式也会在课程中涉及,尽量的寓教于乐。 每期郑大晔校大概会有10周,学生入职之后有的会直接去TWU,有的则会在项目上工作一段时间再去TWU。 组内培训 各个组内自行组织,并不要求其他同事参加。比如某个项目需要一些docker的知识,或者需要AngularJS相关的培训,一方面是找自己组内的专家组织一次内部培训,,另一种是找办公室内相关的专家来进行培训,形式比较灵活。 项目中已经在使用的技术 项目中将要使用的技术 请别的组的专家来咨询 社区 OpenParty Rails Girl 问题 谁当讲师 活动经费 内容如何持久化(人,内部知识分享系统) 如何保证效果(宽松) 由于对任何的话题都没有限制,也没有对参与者的限制,因此任何人只要感兴趣都可以作为讲师。而又由于没有任何的强制措施,参与者和主讲者都凭着自己的热情来组织,这也算是比较独树一帜的事情。 而关于内容的持久化,更多的是为参与者打开一扇新的窗户,或者说洒下一些火星,而至于火星如何形成燎原之势,则完全在参与者自己的自觉。好多次和客户分享了我们的培训机制之后,被问到最多的问题是如何强迫参与者产生热情? 这个问题在ThoughtWorks不是问题,我们在一个人进入公司的最开始,也就是面试的时候,就考察了他的热情,如果在热情上有缺陷,则很可能会直接拒掉,免得破坏我们好不容易构建起来的学习氛围。

January 25, 2015 1 min