Develop web based cross platform mobile app(开发基于Web的跨平台移动应用)

这是我在公司做的一个内部分享的PPT,主要分享的是利用WEB 相关的开发技术开发跨平台的移动应用。

demo 应用可以从 http://librme.com 找到,此外PPT 中提到的技术有:

  • Angular.js
  • Node.js
  • Gulp.js
  • bower.js
  • Ionic framework
  • Cordova / Phonegap
  • CoffeeScript

下面是PPT 资料:

我怎么看敏捷

Agile
去年11月份的时候,我进到了ThoughWorks实习,开始了我的TW生涯,从现在除去今年年初由于毕业论文断断续续的10天左右的请假,我已经到ThoughtWorks1年了,现在我想来我聊聊我眼中的敏捷和我对敏捷的看法。它是比较主观的看法。
首先,我必须得说敏捷并不是完美无缺的,当然也不是所有行业,所有软件项目都适合使用敏捷来开发和管理的。很明显的一个例子就是,你不能用敏捷来开发NASA的航天飞机的软件系统。从敏捷的理念我们会说,我们让开发航天飞机的起飞系统,然后交付给NASA使用,之后再继续交付降落等其他系统,显示这是行不通的,航天飞机不能在仅仅拥有起飞功能的时候就上天啊。敏捷里强调快速交付,快速响应,及时修复bug,因此我们会允许软件存在潜在少量bug的时候让其上线,使用。这在航天飞行系统里面也是行不通的,因为涉及到人的生命,航天飞行系统应该是不允许任何bug的。

但我依然会说,敏捷是一种很好的理念和实践,适合大部分IT企业使用,特别是互联网企业和运行互联网产品的企业使用。

在现在互联网时代,天下武功唯快不破。采用敏捷的实践,初期开发MVP(Minimal Valuable Product)产品,快速上线,根据用户的反馈不断更新、改进自己的产品,开发新的功能,这样周而复始,产品把用户最喜欢,优先级最高的功能永远都放在第一时间开发、上线。根据用户的反馈、统计数据的结果不断调整产品的策略,这样才能立于当今互联网。在我们身边也许Github、 Flickr等都是很好的成功例子。
下面是我对于一些是非的意见:

  • 结对编程能够明显提升代码的质量,让团队成员对代码的熟悉度大幅提升,但是我不赞成至始至终都是结对编程,应该留时间进行单独编程,这样虽然代码质量也许会有一些下降,但是如果伴以TDD对进行辅佐,是不会下降太多,单独编程有助于让dev独立思考,发挥创造力,很多时候会达到意想不到的结果。另外一点结果编程通常达不到两个dev独立编写代码的效率,就像在《人月神话》中讲到的那样,1一个人如果需要开发一个软件需要100填,那么10个程序员10天肯定不能完成任务的,因为期间还需要算上沟通的成本。
  • 关于TDD,确有遇到过几次绞尽脑汁也没想明白怎么测试的case。但是我们如果使用 隔离依赖(即mock依赖,stub行为,如使用mockito中的:given().willReturn();或者when().thenReturn()等)的原则来编写测试,绝大多数情况都会变得豁然开朗,就Java而言,遇到静态方法,我们可以通过间接的调用去测试,对于无返回值的方法(void)我们可以采用验证行为的方法去测试(如使用mockito中的verify()函数)。使用TDD的好处是不言而喻的,用测试代码描述你的需求,表达你想要的结果,既保证了质量也不用担心会做出多余的功能。不过在开发自己的小点子、小创意时,我通常选择Rails和Node.js进行开发因此TDD做得并不好,通产只是选择性的对重要的部分进行测试保证。
  • 沟通胜于一切,跟项目中所有的人频繁沟通,在实际项目中有一次是这样的,对于story中一个对于生效时间信息的描述有些模糊,我没有多想久自己认为肯定的全局的生效时间,但是不曾想到,当多个子产品出现时,就不能依赖全局生效时间,因为全局生效时间是其中最大第一个,而不一定是当前所需准确的生效时间,因此这个sotry在最后给BA 检查的时候才发现这个bug,试想最初如果我没有随便假设,而是马上给BA发邮件沟通,问清楚生效时间,也不会出现返工的情况。我个人认为良好、高效的沟通甚至比写好代码优先级更高。
  • 站会(stand up)既是一种对团队成员工作的可视化,了解彼此的进度等情况,也是锻炼表达能力、增强自信心的好机会。为何这样讲,因为在站会上每个人需要用几句话来概括自己前一天所做的一切,当你讲到你前一天做的一些进步时,团队为你真心叫好,难道不会让你你增强自信心吗?对于站会进行的方式,有团队会选择每个人依次讲解前一天的工作内容;也有人会选择采用按照故事墙的方式来进行,依次对每个列(analysis, ready for dev, in development, test, sign off等)进行浏览等,当讲到自己的那个story时,每个人需要更新自己前一天在这个story上的工作,这样的好处是可以对每个story的情况进行可视化。但是我个人更喜欢前者,这样更加自由,但是目前在工作中基本尝试的都是后者。
  • 另外一点是尽早集成,这点感触很深,大三的时候在一家公司实习,当时做一个原型系统,两三个人做一个模块,到最后快要演示的时候,才把几个模块尝试连到一起做集成测试。结果就是,所有人坐在一起进行的进行各种接口的连接、调用,bug修补。一旦连接成功就兴奋到难以言表,仿佛很长一段时间的工作都没有这一下来得兴奋。系统可以集成后,一直都提心吊胆,担心其中某个东西会不会莫名挂掉,因为集成测试都是使用人肉测试的啊。在展示的时候,各种紧张,安排专人时时刻刻注意到服务器。在敏捷中,我们要求及早进行系统集成和和创建部署环境的脚本,每次CI的运行都是一次集成测试,都是一次服务器的部署。因此不用担心在realse的时候不能部署的情况。不过有一件事情是需要注意的,那就是数据库的迁移,在开发机器,测试服务器你还能每次部署的时候都干掉之前的数据库,重新创建,但是在部署到产品服务器的时候就需要小心了,在Java中我们可以用Flyway 达到类似Rails中的 rake db migrate的效果。

另外,我认为 switch pair(变还你结对同事)、 code review(团队成员坐到一起对团队前一天提交的代码进行浏览、解读),这些都可以让整个团队共享更多的上下文,还可以检查出不到的代码,学习好的代码。
也许明年这个时候我对敏捷的看法又有不少新的见解,到时候再来分享。

使用Gradle 运行jetty 7, 8

为什么我有这个需求呢? 作为一个使用Gradle的新手,今天在尝试将我之前的一个小应用从maven转向 gradle的时候,发现官方的jetty gradle plugin 不能正常运行我的应用,抛出的异常是:

1
    java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getServletContext()Ljavax/servlet/ServletContext;

经过搜索后发现,这是因为 jetty容器中的 servlet API 不是3.0 版本的缘故,继续查证,发现 目前gradle 官方的jetty plugin 版本只支持jetty 6,而 jetty 6 里面的servlet 的版本是2.5。这是从一个Gradle的核心developer那里得到的答案。

Gradle’s Jetty plugin is outdated and only supports Jetty 6.

因此我只能转而向其他途径去解决这个问题,最终发现了Cargo,其官方网站中对Cargo 的解释是:

Cargo is a thin wrapper that allows you to manipulate Java EE containers in a standard way.

简单讲Cargo是一个包装器,让你可以很简单的将你的应用使用类似的配置部署在各种应用服务器上运行。这里我们将使用cargo-gradle-plugin来解决问题:

首先应用插件,在你的build.gradle中添加对plugin的导入和添加依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apply plugin: 'cargo'

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'org.gradle.api.plugins:gradle-cargo-plugin:0.6.1'
    }
}

dependencies {
    def cargoVersion = '1.3.3'
    cargo "org.codehaus.cargo:cargo-core-uberjar:$cargoVersion",
          "org.codehaus.cargo:cargo-ant:$cargoVersion"
}

其次是就是cargo的详细配置了,如,选择你希望运行的WEB 容器,部署的应用和端口等。下面是我的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cargo {
    containerId = 'jetty8x'
    port = 8080

    deployable {
        file = file('build/libs/MessagePushX-0.0.1-SNAPSHOT.war')
        context = '/'
    }

    local {
        installer {
            installUrl = 'http://mirrors.yun-idc.com/eclipse//jetty/stable-8/dist/jetty-distribution-8.1.13.v20130916.tar.gz'
            downloadDir = file("$buildDir/download")
            extractDir = file("$buildDir/extract")
        }
        // homeDir = file('/Users/twer/Documents/lib/jetty-8.1')
    }
}

containerId这是选择运行的容器ID,ID可以在Cargo的官方网站找到。基本上主流的java 服务器都支持,Tomcat, Jboss, Jetty等。
port 应用运行的端口
deployable 填入你希望运行的WAR包的地址,可以一次部署多个war包,如果部署多个就需要多个deployable节点。
local 这里是你的配置你的WEB 容器的地址,你可以选择installer从远程下载,cargo会自动帮你解压,安装,运行;另外一种是homeDir 填写本地的WEB容器所在的文件夹。

当这一切都完成后,你就可以使用 Gradle cargoRunLocal来运行你的应用了。
我今天测试过 Jetty 7,Jetty 8,Tomcat 7这些都是可以正常运行的,另外一个不能正常运行的是 Jetty 9,报的错误是,没有设置jetty.home 的值。但是我们有Jetty 8,应该能满足你的需要了吧,当然最希望的还是Gradle 官方升级jetty plugin的版本吧!

附录:
Cargo
Cargo-gradle-plugin
我的示例地址

毕业生成长记——如何成长为一个合格的程序员

        上周六去成都Open Party 讲了自己怎么从一个毕业生成长为一个合格的程序员的感想吧,的确自己还有很多问题,最主要的是对自己写的东西和对自己的演讲不够自信,然后分享的的东西有些零零散散,希望以后可以在这方面做得越来越好。

还是把PPT分享出来吧,也算做是一篇博客,这个东西还是花了我不少心思在里面的。

部署一个独立的Jar包到远端maven 仓库

必备环境:

  • 推荐Java jdk 1.6及以上
  • 推荐maven 3.0.0以上

假定我们需要将C:/ sqljdbc4.jar部署到我们的仓库服务器(http://yourrepo.com/nexus)
首先我们需要在本地配置maven的server节点,该节点用于从仓库下载或者上传包时用于进行身份验证。(下载是可能会用到,视仓库服务器设置而定。)
通常允许上传到两种仓库:Snapshots、Releases,分别为快照版仓库,主要用于存放不稳定的开发包,后者用于存放稳定版本的包。
节点内添加如下内容:

1
2
3
4
5
6
7
8
9
10
<server>
  <id>snapshots</id>
  <username>你的用户名</username>
  <password>你的密码</password>
</server>
 <server>
  <id>releases</id>
  <username>你的用户名</username>
  <password>你的密码</password>
</server>

打开cmd,将其定位到你要上传的jar包的文件夹:
类似地输入以下命令:

1
mvn deploy:deploy-file –DgroupId=com.huacloud.jar –DartifactId=sqljdbc4 –Dversion=1.0.0 –Dpackaging=jar –Dfile=sqljdbc4.jar –DrepositoryId=snapshots –Durl=http://222.197.188.5:9000/nexus/content/repositories/snapshots

需要注意的是 –Dversion 、 -DrepositoryId 、-Durl 是对应的,如版本是snapshot ,仓库id 也应该是snapshot仓库的ID,仓库地址也需要填写snapshot仓库的url。
如果cmd 当前路径与jar包的路径在同一文件夹下,-Dfile 直接写文件名即可,如果不在同一个目录下,需要在-Dfile 后面写上文件的绝对路径。

如果当你运行上述命令时出现如下的错误:
The goal you specified requires a project to extcute but there is no POM in this directory. Please verify you invoked Maven from the correct directory.

通常是由于操作系统之间的差异,你可以尝试这样:

1
"–DgroupId=com.huacloud.jar"

给所有的参数就加上双引号包起来。应该就可以解决问题了。
Maven deploy jar to remote repo

3rd week in TWU

这个系列的感受都是我在印度参加TWU的所有感受,感受来自我,难免比较主观,当然我也尽可能的表达我所观察到的客观的东西,第三周,基本上是我最累的一周,这周有忙项目的事情,有忙计划出去玩的事情,也有忙小session的事情,几天晚上都是凌晨1点才睡,所有导致这一周整体来说,状态不太好。当然还是有不少感受的。

疲惫

首先说疲惫吧,为什么会疲惫,当然原因是多方面的,一方面TWU 的安排还是比较满的,早上7点办起床,吃早饭,8点坐上车到HOTEL,开始一天的培训和工作,基本上晚上7点到7点半下班。上午,下午分别有Tea Time可以休息,不过这一周我没有在Tea Time休息,事情比较多。一方面我们还有P3 case study 需要我们花些时间在上面,还有如同我之前说的,因为我自己和其他几个同学在计划周末外出游玩的事情,也花了不少时间,还有我发现Pair 是相当消耗体力和脑力的,特别是当Pair 高度集中,并且Pair之间有一些能力差异的时候,花在解释上的时间会不少。不过经过周末的休整,状态好了不少。而且想到接下来是倒数第二周了,开始变得期待回国了。

项目改进

上一周也提到,经过第一个Release的失败的经验教训后,我们项目组本身也在不断的完善改进自己,项目组给自己提了不好action,来对团队进行流程上的规划,还有有一定作用,不过这个东西也产生了一个负面影响,那就是我们决定在Sign up story之前不做假设,不盲目开始开发story,这导致本来就只有一周的release,我们丢掉了不少时间来完成story,我们利用那段时间修改了一些release 1的story的bug,又交付了一些。不好的地方就是,我们星期五才sign up story,这一周星期二又要进行release 2 的show case,也就是我们只有不到两天的时间进行开发,测试,还不包括这之间一些session 和class 会占用我们一些时间。
此外,也许因为时间的关系,上周星期五,QA希望我完成一个story,但是那个story里面还有一个很重要的点,是没有确定的。 QA希望我先做确定的点,后面再来改,但是我拒绝了,因为不确定的那点就是这个story中相对比较复杂的一点,而且我也认为这样做assumption容易导致项目返工,最终没有接受那个story。今天在和一个同学pair的时候,又发生一件让我很纠结的事情,我发现这个story之前的部分,很多地方都没有测试,而且我们今天的时间和任务很紧,当我们希望在这个基础上添加新的功能的时候,我的pair告诉我,他认为我们现在应该尽快完成现在的这个story,测试可以后面来写,我很疑惑的望着他。 是的我知道,我们小组中,有些同学的目标不一样,更何况今天是我们的show case之前的最后一天,想尽快story 是对的,但是保证质量也是对的。最终在大部分地方,我们采用了测试驱动开发,有小部分地方因为需要做spike的时候,TDD做得不好。代码也没有进行重构,时间已经来到了下午7点。
其实这个时候我是很纠结的,一方面我自己在这次TWU中,希望聚焦好的代码质量,另外一方面我们身处在团队之中,团队成员的coding能力不一致,更何况我们面临的是很零碎的工作时间,当然也是很紧的工作时间,我们必须从中进行取舍,这算是我在印度TWU面临的比较大的困惑了。

关于P3

来之前我们就听说了P3在如今的TWU的重要性,还有也听说了我们中国的童鞋大部分对这方面不太感冒,这次来,我也算颇有感触。我们中国的同学在这方面的确表现得不是很好,首先,讲话的流畅性是个很大的挑战,其实我还是觉得有文化的因素在里面,感觉我们没有特别强烈的愿望想表达自己的意见。当然在P3的session上表现得不那么好,并不代表我们什么都没做,就我自己而言,在两次P3 case stuudy 中,我都和电话那头的Thoughtworks同时,讲述我们中国的情况,介绍了我曾经干的类似的事情。我承认我可以做得更好。

关于积极参加项目管理的工作

参加这次TWU,我在参加项目管理以及与客户沟通方面,我是有不少期望的,但是事实说明到目前位置我做的并不好,一个事实就是,今天我和我的pair去跟PO确定细节,PO问我叫什么名字,说没有在之前的会议里面听到太多发言,我才意识到我在这方面做得多么不好,其实上周Coach JK也给我提过这一点。我的“借口”就是,项目里面不知道什么时候突然就冒出两个在这方面特别主要的童鞋,做了很多这方面的事情,我不太好再去插手这方面的工作,此外我觉得跟PO的交流、沟通很重要,我怕自己跟PO交流沟通不好,会影响团队。
当然这一切都是借口,其实现在这个环境,即使我们跟PO交流,沟通得不好,对我们的好处也是远远大于给我们的影响的,因为PO也是thoughtworks,我们不用太忌讳,太拘束,当然也要当人家PO那样正式对待,另外其他两个同学主动去承担了那些工作,为什么我没有积极的参加?其实说来,还是没有完完全全跳出舒适区,其实就像我在成都的项目里面类似,我在做编程之前的事情,我自己也知道并不好,比如跟BA交流,当然这并不是说我的开发的代码工作就做得多么好,而是我因为coding是我喜欢的工作,我觉得挑战更小,所有在上面更称心一点。还是继续加强在和客户、BA、QA方面的工作吧。增加能力的宽度。

总结

我觉得,我在第一周,第二周的表现是要明显好于第三周的,也许是因为疲劳,也许也有一些松懈在里面吧,然后跟不同的人聊天,体会到公司搞这个Thoughtworks University是多么不容易,是花了多少的人力物力,我想我们每个人都应该珍惜这段时光,当然也不得不说,有很多是需要继续改进的,部分Session的质量我觉得还是可以更好的,此外我觉得最恼火的问题就是公寓的网络问题(公寓是公司花钱租的,算是公寓式酒店),基本上一直处于瘫痪的状态,除了可以聊QQ、Skype,有些时候能打开网页以来,基本上一直都处于在刷新页面的状态。希望可以早点解决,以后的童鞋也不用这么恼火了。

Second week in india

上周是TWU的第二周,Session 变少了,取而代之的是我们的项目“Freewheels”,这一周给人的感觉的很累,每天很努力的做Story,也帮其他同学解决一些问题。

Session

这一周我们还是有几个Session, 加上上周学习的有 TDD, Mock与Stub, 重构,非技术的有 TW Finance, Story的生命周期。也许是因为Story的原因,让我对某些Session的印象都模糊了。最清楚了应该算是Mock与Stub了。
来印度之前一直没有搞明白Mock与Stub的区别,我只是知道他们都是用假的对象来模拟真实的对象。而通过这次的Session算是搞明白了。
Coach 给了个题目,这里有三个类 CashRegister(接口), Printer(接口), Purchase, 现在在CashRegister中会调用 Printer打印 Purchase,现在需要测试该方法,问如何测试, CashRegister, 和printer 的执行方法 均为 void,无返回值。不能用Mockito 框架。
拿到这个题目,我是完全没有头脑,因为我之前用过的 测试都是通过结果来测试数据的,而这次测试的方法不仅没有返回值,而且被测试的类还是接口。
就这样按照coach的指导,基本模拟出了简单版的Mockito来测试这个方法,如果使用Mockito我们只需要使用:

1
 verify(cashRegister,times(1)).process();

最后coach总结出了,Mock和Stub的区别在于,Mock会验证,而Stub则是你让他干什么,他就给你什么。瞬间感觉豁然开朗的感觉。

项目

从这周开始,项目就是TWU生活的主体内容了,当然coach们是希望我们把session中学到的东西全部利用到项目上面来,但是结果是残酷的,第一周我们表现得并不好。在项目正式开始之前,我们两两Pair做了一个在用户注册表单中添加地址、城市、国籍、邮编等信息,当然也需要在用户详情页面中显示。有人半天时间几乎完成了大部分story,我和我的pair完成了1/3左右的工作量,其他同学也或多或少都完成了一些。演示代码的时候,做得很快的那对pair,他们将所有用户地址相关信息也都全部添加到用户表中,其他实现也都是在之前的基础上进行复制,粘贴,修改,添加。从这个时候开始我就明白了,每个人来TWU 的目的真的是不一样的,有些人是想提升自己的技术能力,能多学一点东西,有些人希望用自己的能力帮助团队提高效率,解决问题,有些人希望帮助管理、组织团队。
在之后的Iteration planing meeting上面,大家普遍对小组完成story的能力比较乐观,我们小组计划在一周内交付40点。
何为1点,在界面上为登录用户显示欢迎信息为1点。为用户注册、用户详情查看、管理员详情查看页面,当然包括编写funtional测试,这个story是5点。按照我们自己的计划我们一周内可以交互 3/5 6 5 = 50点。大家想到每天可能会有session会耽误时间,所以将点数减去10点,因此我们需要交付40点。我们小组来自中国的两个同事,包括我在内,是反对交付40点的。也许是因为在项目上滚过一段时间吧,知道40点没这么容易。
在接下来的这一周里,大家也意识到了时间的紧迫,我们也知道了我们小组是计划了最多交付点数的小组,同学们都非常努力,每天的standup 也很积极,story 墙上的story也在墙上快速流动,似乎我们就可以完满完成我们的交付点数了。
但是,我们很多地方并没有按照session中学到的东西来做,在讲story挪到ready for dev 的时候我们并没有对AC进行详细检查,所有story也没有mockups,所以必须靠我们自己来想象。比如dev在拿新卡的时候,基本上没有和QA(因为我们项目中没有BA,所以QA既当妈,又当爹)对story进行kick off,遇到story里面描述得不清楚的地方也许首先会自己想想怎么样最好,然后再去问QA和PO,有时候我们也在做assumptions,dev开发完story后有时候并没有跟QA进行演示和确认。所以我们看到墙上的story流动的比较快。
到了showcase的那一天,在showcase 之前的10分钟,不少同学都还在提交代码,我也在其中,当然我们的QA也在很负责的进行代码的手工测试,那天我做聪明做了很多UI的美化工作,但是结果是把两个地方弄巧成拙了,一个地方是我自己做了assumptions ,给商品的展示进行切换排序,在修改一个按钮的css样式的时候,我也没想到那居然会影响到其他一个页面,当然之所以没影响,是一个一个同学copy另外一处的代码,并且没有修改。
毕竟因为我们项目的细节大部分没有测试到,最后我们只交付了4点。当然有很多story是因为bug的原因不能交付。

在项目上的第一周,就给我们的感触很多,当然教训也是很多,现在已经太晚了,已经凌晨1点了,这里只想提几个问题:

  • 在这样的情况下,我们到底是更多的关注与每个人定的自己不同的目标,还是全心全意把所有的心思都放在项目上?
  • 在这个情况下,到底是项目的正常交付重要,还是保持代码的质量更重要。
  • 在TWU中4个小组,共享一个client,只有一个印度同事来担任PO适合足够?因为很多和story相关的事情都需要和client确认。
  • 在这样的情况下,能力稍强的同学是否应该快速自己的速度,帮组团队完成交付目标,而放弃与某些编程能力相对较弱的同学pair、交流?
  • 在这个情况下DEV 是不是只应该关注自己的开发和单元测试、functional测试任务? 在我们项目中没有BA,12个DEV,2个QA
  • 很多同学为了尽快完成story,通常晚上也会pair到较晚的时候,最近逐渐发现,不少同学已经开始疲劳了,早上的session的活跃度感觉有点下降,这样到底是不是对的?

这些都是我自己心里面的问题,我有一些想法,但是肯定里面有些是很主观的,不对的。所以就不写自己的想法了,暂且提及问题。

First week in India

TWU 33
来印度已经快两周了,完全没有不适的感觉,每天都很充实而又忙碌,就连周末都是各种安排。只有在聊天的时候才会有思念的情绪涌上心头。这里记录下第一周的感受。
总的来说第一周很多Session,从很入门的session 逐步深入,到接触到一些之前没有了解到或者没有深入的东西。每天的收获还是很多的。就像coach们说的那样,你来TWU不是为了和别人比较,而是和自己比较,让自己有成长。今天中午我们中国童鞋吃饭的时候还在聊,一个童鞋说,感觉和老外Pair让自己的编程速度更慢,因为你需要先解释你的意图,在你coding的还需要不断的解释。其实我有时候也会有这样的感觉。但是我心里很清楚,我作为一个来公司几个月的毕业生,在coding方面可能会比一些grads好一些,但是我这次来的目的是体验和全世界不同国家的同事一起工作、写代码、生活,更多的是这种经历、同事之间彼此的分享,各种方面的分享。即使完成某些代码对我来说相对比较容易,但是我能不能用更好的方式,我能不能把我的想法完整的表达给我的Pair,我能不能分享一些快捷键、一些思路给我的Pair。这些都是我很看重的,他们都是我的目标。
另外一方面,几乎现在所有认识我的人都不会说我很内向,但是我其实自己知道,我真的是算是一个内向的人,很多时候我没有勇气去做一些事情,所以这次我给自己的目标也有在小组里面更活跃一些,多多表达、贡献自己的意见,虽然我的英语单词量不大,但是并不妨碍我表达出我的意思,我还清楚的记得,昨天上午session的时候,我中途因肚子不舒服去上厕所,我还在马桶上摸出手机查“拉肚子”这个单词怎么说。一些都是这么不可思议。哈哈。

Feedback

言归正传,首先聊聊Feedback Session,在我们公司大家都知道,这个很重要,但其实很多时候,至少我在这方面做得并不好,不太敢当面向其他人要Feedback,怕别人指出自己不好的地方,会尴尬,。这些都是需要提高的。在来印度之前,在成都听过Feedback 的session,当时真的是深有感触,这次再听一次后,加深了理解。

  • 如果你想要给一个人Feedback,请一定要记得营造一个安全的环境,一定要让接受者感到安全,在你给一些消极的Feedback的时候,一定要根据事实来,而不是直接就说,我觉得你怎么怎么不好,此外不要带着责备、埋怨的口吻。当然一次不要给太多的Feedback,不要让接受者感到沮丧。总之,不管怎么样,你应该给予接受者信心和鼓舞,给予他改变的力量。
  • 作为接受者,当然很重要的是不要一听到别人消极的Feedback 就一味的抵触、狡辩,有则改之无则加勉。要知道一个人要给出消极的Feedback远比给出积极的Feedback难上很多,所以不管怎么样,我们都要怀着一个感恩的心,谢谢给你Feedback的同事。
  • 快速、主动的 给和接Feedback
咨询师

接着是咨询师的session,我们每个人都是咨询师,而不是只有DEV才是。根据我在项目中的经历有一点我印象特别深刻,那就是“Domain Language”,大多数情况下我们面对的客户都是没有太多IT和敏捷 context的人,我们不能用我们在公司内部讨论的那一套去给他解释,而是要学习客户的Domain Language, 要用用户懂得的语言去给他解释。 此外当你在项目上工作时,要时刻记得,你这样做能为客户带来什么样的 Business Value,能带来多少的Business Value,如果你的工作不能给客户带来Business Value,那人家为什么要让你做,要为你做的付钱呢。
在这个session的 角色扮演游戏中,我就扮演了一个客户,几位咨询师想要花5天时间去重构代码,然后他们试图说服我同意重构。我就抓住我不懂重构,让他们给我解释什么是重构、为什么代码可以使用要重构,他们怎么能保证重构的代码运行起来更好,为什么我要花5天时间多支付那么多钱去让他们去重构我可以使用的代码。结果是我这个可恶的客户赢得了讨论,他们回答不上来我的这些问题。
仔细想想,也许我们在遇到其他客户的时候也许遇到这样的问题,怎么样让重构体现出客户的Business Value,怎么样用客户容易理解的语言去说服客户,这真是一件很有挑战性的事。

QA

在一个关于QA的session中,通过一个画画的游戏我第一次了解到QA和DEV 也应该pair,而且他们一起pair的效率比 dev做完以后,交QA检查,再交回DEV改进有很大的提高。另外一点,QA 不仅仅是tester,QA 也应该参与story生命周期的绝大部分,比如和BA一起写story,这样更能保证 acceptance criteria 是可测试,容易测试的。瞬间对QA肃然起敬。

Agile 团队

每个任务都可以多个团队成员来共同负责,一个团队成员应该在团队中承担多种角色,而不是仅仅一种。 时刻记得你是团队中的一员,而不是一个人在战斗!!

我的生日party

很荣幸在印度过了自己的一个在国外过的生日,我的室友是第二天,所以我们一起过了生日。很感动,我们的中国妹子们交了老外们学用中文唱生日快乐歌,很感动。这个生日party,绝大部分的twu grads 都来了,也许40多个人吧,还来了一个coach。每个人都带来零食、饮料和我们一起分享,而我们准备一个大大的蛋糕、美味的中国方便面、一些筷子、中国钱币。整个party的高潮应该是我被满脸摸上蛋糕,被人抬起踢屁股吧(话说这是印度的一个传统)。总之很开心的生日。

番外篇

就像我之前说的,他们叫外国童鞋唱中文歌,我们也教了很多人学中文,很多人都是很主动的让我们教他们一些中文单词,我们这次去的中国童鞋我感觉大家都还是比较合伙吧,大家都会主动去融入这个集体中,至于我这次只有我一个男生,所以我只有到处跟大家一起去吃饭,活动了。我也很享受在团队中的感受,这次还有两个从澳大利亚和新加坡来的华裔女生大家都玩得比较来。

据我所知我们大家也没有遇到对于吃的东西不习惯的!这这边吃的公司负责的早餐和午餐都是相当美味、可口的感觉。很幸福的感觉。

期待我们这周星期五的 Chinese Hot Pot Night,我们邀请了所有人。 唯一很担心的是电力负荷的问题,因为我们希望可以准备4口火锅。在这边已经遇到几次跳闸了。
加油!