最近的问题特别多。近几天再看得一本书《梦断代码,徐兴问我这是一本关于什么的书,我告诉他是一本寓言,一本关于软件开发,产品开发,软件工程,软件管理的启示。
其中有一个比较启发的地方,编程到底是不是艺术。很多非计算机人士经常会看到莫名其妙的符号和无与伦比的抽象后折服于程序员的惊人技艺。但这些真的是艺术吗?我从一开始就在怀疑这个。我们看到音乐,绘画这些艺术,无不是先从研究先人的杰作开始,但是很多时候我们在开始编程时是从研究他人杰出的代码和开发经历开始的吗?很多时候都不是。
当然上面这个不足以挑战“编程是艺术“这个结论。书中举了一例,如果所有的作家都有自己的“公司“,只有海明威的公司的人才能读到老人与海,你能想象还能接出什么丰盛的文学成果么?
计算机,或者编程的教育方式没有鼓励过类似“推敲“这样的行为。而这些是其他艺术必须也是最为重视的东西。除非编程真的不是艺术,或者说是另一种艺术,廉价的艺术。
编程到底是不是艺术?程序员到底是艺术家还是工程师?我现在还看不出来。
23:40 2008-6-15
今天和ricky聊天关于公司目前的状况。印度人逐渐爬到中国人的头上来了。先声明一下,我这里没有狭隘民族主义的意思,只是想分析为什么中国人在IT这方面搞不过印度人,师夷长技以制夷嘛。
说中国人在IT方面搞不过印度人主要还是指外包,服务这一块。其实这个问题一直都有人在分析探讨,其中主要的因素不外乎:
1.语言优势
2.重视流程化,标准化
3.先发优势,也就是一定的历史渊源。持这种观点的同志也相对乐观的认为,中国未来将和印度并驾齐驱甚至超越
4.不是技术,之所以强调这一点是因为我们通常所认为印度人的技术烂恰恰是他的优点,易于管理,相对不会那么毛躁。我所见的印度人并不像中国人那么热衷于钻研技术,而更注重沟通,而这正是consultant最重要的素质。
上面这四个因素都有道理,只是所占比重的问题,我更倾向于最后一个所引发的一系列结果 - consult的能力,这也是中国人之前最不重视的(可喜的是现在我们也在组建自己的BA团队)。我所发现的印度工程师,技术也许并不是出类拔萃,也未必夯实,但绝对“很会说”,尤其是在和客户或者manager沟通时候,作为旁人我都觉得说的真的很得体,既把1个说成3个,又可以把推卸责任说成不是推卸责任,而且总是毕恭毕敬,有条有理。
而反观我们自己,嘴笨把一个说成3个的时候一听就是在吹牛逼,推卸责任的时候说着说着就开始胡言乱语,要么恭敬的过头没观点,要么干脆p都不吭一个 — “老子干的好不好你自己看吧,不赏识老子,老子就闪人”。不是英不英文的问题,用中文都是这个鸟样子。
不要误解,我并不赞同吹牛和推卸责任。只是觉得中国工程师被印度工程师边缘化主要还是沟通的问题。也许我们应该更多地从这个方面去改进。当然要得体地沟通,英文还是要加强(至少我是要)。
实践的一小步-代码质量的一大步
作者:Steven Hale December 14, 2007
翻译:ZhangV 2008-2-18
原文出自:DevX.com
原文链接:http://www.devx.com/Java/Article/36231/0/page/1
假设持续整合是你开发过程中很重要的一部,你也很想把代码覆盖检查并入你的自动构建过程.但是如何设定覆盖率目标呢?经验丰富的代码覆盖支持者会建议你75%,85%甚至100%.
通过对项目中的代码分析,我意识到需要设定比上述数据低得多的目标.我不想成为团队中的Cathcart上校(Josef Heller的小说<<第22条军规>>中的人物,因为每当部下已经达到当前的飞行任务次数时,他就会设定更高的任务次数,虽然Yossarian不断地完成飞行任务,但却似乎永远都无法完成这个总在变化的次数,小说中最后Yossarian开小差逃到瑞典-译者).
我选择增量改进的策略而不是专制的设定更高的目标.为了成功的执行这个策略,每次构建都必须达到比之前构建更高的覆盖率.通过每次一小步的提升,来最终提升代码质量.
以下介绍如何使用Cobertura和Apache Ant来实现这个增量改进.
单元测试,代码覆盖,持续整合
这三个概念已经被广泛的接受为最佳实践.事实上,大多数程序员知道他们必须要单元测试.如果你还不知道,让我来引用Google研发总监Peter Norvig的名言:
“如果你觉得不需要写单元测试,把所有原因写下来到一张纸上.仔细的揣摩这张纸.然后,扔掉这张纸开始写单元测试.”
但是谁来测试测试人员呢? 也就是说,你怎么来确认你写了足够的测试呢?这些是非常宝贵的信息,因为那些没有被测试覆盖到的代码正是最耗费你经历的地方.一个解决办法是使用代码覆盖工具,它们会告诉你有被测试代码的百分比,然后加入一个代码覆盖检查到你的持续构建过程.如果你的覆盖检查不通过,那么构建也该被认定为失败.
在我的增量改进策略中,我选择Cobertura是因为她4个定义完整而简单的ant任务扩展.其中之一 cobertura-check,当代码覆盖率没有达到要求是会认定构建失败.例如下面这个例子,当覆盖率小于80%时,Ant会认为构建是失败的:
<target name=”coverage_check”>
<cobertura-check totallinerate=”80″/>
</target name=”coverage_check”>
但是,你可以使用之前的覆盖率来作为当前检查的标准.通过几个Cobertura的任务以及两个核心的ant任务,你就可以达到这个目标.而不需要担心是否应该考量 代码行率(line rate),分支率(branch rate)或者其他的覆盖数据.你的目标是改进,而不是一个绝对的硬性指标.
创建一个XML格式的代码覆盖报表
创建好ant任务后,你可以加入增量覆盖率检查到你的构建脚本中,第一步是用cobertura-report任务创建一个覆盖率报表:
<cobertura-report format=”xml”/>
下面是一个生成的报表:
<?xml version=”1.0″?>
<!DOCTYPE coverage SYSTEM “http://cobertura.sourceforge.net/xml/coverage-02.dtd”>
<coverage line-rate=”0.43612334801762115″ branch-rate=”0.48344370860927155″ version=”1.8″ timestamp=”1181043899853″>
<sources>
<source>./src/java</source>
</sources>
<packages>
…
</packages>
</coverage>
确保你把这个文件保存安全的地方(或者放到你的版本控制系统),因为之后你会用到他们.
从报表中得到覆盖率数据
一开始你可能会用Ant的XmlProperty任务来直接获取代码行率(line rate).但是这种做法有几个问题:
1.Cobertura的行率(line-rate)是十进制小鼠,但是cobertura-check是用整数形式的百分率
2.在一个实际的项目里,coverage.xml可能会很大,使用XmlProperty可能会造成内存不足的错误
我建议使用Ant的XSLT任务来获取你所需要的数据
<xslt in=”coverage.xml” out=”build/coverage.properties” style=”src/xsl/coverage.xsl” />
这个简单的xsl模板生成仅仅包含你所需要的数据的属性文件:
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″>
<xsl:output method=”text” omit-xml-declaration=”yes”/>
<xsl:template match=”coverage”>
total.line-rate=
<xsl:value-of select=”floor(@line-rate*100)”/>
</xsl:template>
</xsl:stylesheet>
注意方法:floor(@line-rate*100), 会把行率转成一个整数,生成的coverage.properties文件只有一行:
total.line-rate=44
这个属性文件仅仅是一个临时的文件,构建之后你可以把它清理掉.
使用Ant的property任务读入这个属性文件中唯一的值total.line-rate:
<property file=”build/coverage.properties” />
然后你可以把之前的”80″替换为新的Ant属性值:
<cobertura-check totallinerate=”${total.line-rate}”/>
完整的例子
最终的build.xml应该是这样(其他的任务省略掉):
<target name=”coverage_check” depends=”check_against_previous_rate”>
<antcall target=”coverage_report”/>
</target>
<target name=”coverage_report”>
<cobertura-report format=”xml” destdir=”.” />
</target>
<target name=”check_against_previous_rate” depends=”coverage_xml_to_properties”>
<property file=”build/coverage.properties” />
<cobertura-check totallinerate=”${coverage.line-rate}” />
</target>
<target name=”coverage_xml_to_properties”>
<xslt […]