- 浏览: 4821553 次
- 性别:
- 来自: 上海
博客专栏
-
robbin谈管理
浏览量:137075
文章分类
最新评论
-
xly1981:
领导者是团队的灵魂。深入一线的过程,包括代码review,能帮 ...
robbin谈管理:改造团队的经验(2) -
jiehuangwei:
像这种总结比较性的ppt文档可以多发啊
Web并发模型粗浅探讨 -
linux1308:
看完学习到了很多东西,感谢推荐!
推荐一篇很好的RoR部署方案性能评测 -
zweite:
直接对搜索的结果进行缓存是不是会更快一点呢
漫谈应用缓存的命中率问题 -
kaogua:
现在已经是ruby2.0了, 不知道这个的效率是怎么样的, 是 ...
Ruby作为服务器端应用已经成熟了
在参与这个讨论的过程中,产生了一个新的话题,很想和大家探讨一下:
http://www.iteye.com/topic/33890
这是一个存在于大家心里常识了。我承认我自己在潜意识里面也觉得静态强类型语言适合开发复杂,大型系统。而弱类型脚本语言不适合开发太复杂,太大型的项目。但是在参与这个讨论过程中,我突然开始置疑这个观点,事实究竟是不是这样的呢?
先定义一下标准:
强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#
弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
对于像Java来说,IDEA/Eclipse确实在代码感知能力上面已经非常强了,这无疑能够增加对大型系统复杂系统的掌控能力。但是除了Java拥有这么强的IDE武器之外,似乎其他语言从来没有这么强的IDE。C#的Visual Studio在GUI开发方面和Wizard方面很强,但是代码感知能力上和Eclipse差的不是一点半点。至于Visual C++根本就是一个编译器而已,羞于提及Visual这个字眼。更不要说那么多C/C++开发人员都是操起vi吭哧吭哧写了几十万行代码呢。特别是像Linux Kernel这种几百万行代码,也就是用vi写出来的阿,够复杂,够大型,够长生命周期的吧。
也就是说静态类型语言可以保障package的命名空间分割,从而避免命名冲突,代码的良好隔离性。但是这个观点也缺乏说服力。
静态类型语言中C,VB都缺乏良好的命名空间分割,容易产生冲突,但是并没有影响他们做出来的系统就不够大,不够复杂。
而Visual C++开发的DLL版本冲突也是臭名昭著的,似乎C++的命名空间没有给它带来很大的帮助。
而动态类型语言中Ruby/Python/Perl都有比较好的命名空间,特别是Python和Perl,例如CPAN上面的第三方库成吨成吨的,也从来没有听说什么冲突的问题。
诚然像PHP,JavaScript这样缺乏命名空间的动态语言很容易出现问题,但是这似乎是因为他们缺乏OO机制导致的,而不是因为他们动态类型导致的吧?
说到大型系统,复杂业务逻辑系统,Google公司很多东西都是用python开发的,这也证明了动态类型语言并非不能做大型的复杂的系统。其实我个人认为:
动态类型语言,特别是高级动态类型语言,反而能够让人们不需要分心去考虑程序编程问题,而集中精力思考业务逻辑实现,即思考过程即实现过程,用DSL描述问题的过程就是编程的过程,这方面像Unix Shell,ruby,SQL,甚至PHP都是相应领域当之无愧的DSL语言。而显然静态类型语言基本都不满足这个要求。
那静态类型语言的优势究竟是什么呢?我认为就是执行效率非常高。所以但凡需要关注执行性能的地方就得用静态类型语言。其他方面似乎没有什么特别的优势。
Jack同学,你这想法真的大错而特错了。PHP就是因为是动态语言,就是因为不需要复杂的IDE,不需要调试器,只有一个解释器,所以菜鸟才能够很快上手,所以互联网70%的网站都是PHP开发的。不瞒你说,现在也有很多很强的PHP IDE出来了,例如Zend Studio之类,但是我还是觉得UltraEdit好用,为啥?简单呗!
互联网网上真正用静态类型语言开发的网站所占的比例还不到20%,而超过80%的都是脚本语言开发的。
我用Eclipse已经有三年了,但是Eclipse的很多功能我到现在都没有掌握,调试器也只不过会最基本的功能而已。你说那么普遍的字符串拼接SQL的错误,Java里面还不是一大把吗?难道Eclipse可以限制初学者不用?HTTP Session里面随便乱塞结果集Eclipse可以避免?数据库连接不关闭Eclipse可以编译检查出来?
这些web开发当中最容易犯的错误,反而是脚本语言不容易出现,为啥呢?因为脚本语言是进程模型,不需要关闭数据库连接,内存当做不保存Session,所以Session可以随便乱塞东西,SQL拼接都提供了很强的字符串检查和过滤机制。
这不是我说瞎话,我帮很多Java系统做过性能排查和调优的咨询,Java新手的不良编程系统破坏力是及其惊人的,而PHP新手很少会在这种事情上遇到困扰。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
本以为这没什么好争的,
IDE作用大,不只因为是菜鸟。
我想知道有那位高手做项目时有好的IDE不用的。
用rails提高了效率,所以rails好。用IDE也提高效率,怎么IDE的就没啥用了?
做到一次code完,一次编译通过已经是难能可贵了。
还不需要Debug,那简直是讲故事。
别介,下面这句话是你说得吧
根据这话里的意思,只能说明你做的就不是TDD,所以没必要戴TDD这顶高帽。
前面已经说过,TDD中的测试指的是准黑盒的功能性测试,没办法顾及到语句覆盖率的(这个是覆盖的最低级的一层).
robbin是说过这句话,但是你好像没有说过啊。你说得只是单元测试要覆盖。没有说针对什么样的语言.
或者,你从来就没有编写过java代码,那也是个说法。
或者,你编写java程序的时候就可以漏过getter/setter的测试,那不就结了,和我的结论一样,就没语句覆盖的事情了。
跑题了吗? 前贴已经明确说了. 对于logger为null的情况,本身就不应该在使用这个logger记录日志信息的地方判断. 你如果对这个说法有异议,请提出来。
别激动,没说你要打谁啊,只是说你说那句话的时候纯属自娱自乐.因为没有人否认你的观点.
但是你现在的后续解释就有问题了.如果你想通过
这句话来推导出
这个逻辑也太不靠谱了吧. 难道你认为人就可以做到让代码正确无误? 如果不是这么认为的,那前提和结论根本就没有联系.
这个只是讨论而已.如果每个人都只是表达自己的意见而不愿意在讨论中深入,那开个论坛干吗?
我觉得在论坛上有非常重要的一点. 那就是,每个人都是写给观众看的.
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
robbin,那是不是可以认为这样的工作方式对开发人员的素养和开发习惯都有比较高的要求?你能不能推荐一些介绍如何采用feature驱动的方式进行团队协作开发的资料?
像XP就是比较适合RoR的软件开发方法阿,先讨论userstory,制订userstory card,然后一个card一个card进行小步骤迭代实现。
其实我觉得XP对开发人员技术素质要求不高,但是像沟通能力,团队协作的习惯要求比较高。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
code once, run everywhere? 新广告词?
也许比较好的折衷是Erlang那种动态语言+类型检查器。C这么容易出错,我们靠lint/splint也挺过来了。
首先我没有扯“什么是TDD中的T这个冷饭”!
其次,“但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),个代价和能力不是多数人所愿意付出的” 是谁得出的结论?
基于我个人的实践,我不敢苟同。
robbin已经说了,ROR没有get set. 再说我针对的是你那个logger的例子,请不要跑题。
兄弟,没人说编译器还是单元测试能保证代码正确无误啊。没必要自己树个靶子自己打吧。
拜托,我说要打谁了么?我只是说工具和流程不能代替人!仔细读读好么?
关键是代价。如果不考虑代价,那么每个项目团队都会去做这件事情。
TDD的优劣每个人都有自己的看法,我只是表达我的意见。我不会把自己的看法强加给别人,我也没这个能力。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
单元测试覆盖到这些语句很难么?实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本。
遵循TDD,就会在不知不觉中覆盖到所有代码?无语中....
严格的说,TDD中的测试做的是准黑盒的功能性测试,而不是白盒的结构性测试。怎么可能起到覆盖所有代码的作用?
从测试本身来说,单元测试能做的比TDD中所谓的测试要细化得多。但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),这个代价和能力不是多数人所愿意付出的。
难道又要开始炒什么是TDD中的T这个冷饭了么?
再说逃离单元测试的覆盖值得那么沾沾自喜么?logger为null是编译器能检查出来的?
拜托,难道你在写java程序的时候真的测试了getter/setter这类方法?如果是的,恭喜你.........
如果不是,赶紧去补上............
至于logger为null,有两种情况,编译器能够检查出来logger未初始化就使用的错误(当然,如果必要,人为设置为null也可以骗过编译器)。
另一种情况,logger被在语义上合理初始化了,但是全局logger初始化的时候出错,这个时候,出错的是这个初始化的地方,正确的捕获位置应当在调用初始化的点,难道需要推迟到在使用logger来记录信息的位置来捕获? 在前面已经说了,这类logger语句中的错误,基本上不应该在此处被捕获。里面的隐含意义是:如果在初始化失败点被捕获,还有补救的可能,但是在日志记录点被捕获,基本就88吧。兄弟我看了那么多年程序,还真没看到过给logger.xxx语句套上try/catch的。而如果因为logger语句可能的问题而给整段代码套try/catch,那就是最愚蠢的做法了,一死全挺,而且程序死在次要功能上,哭都没地方哭。
另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到!
兄弟,没人说编译器还是单元测试能保证代码正确无误啊。没必要自己树个靶子自己打吧。
但是单元测试给我们创造最多的机会来发现错误,而TDD给我们更多利用单元测试的机会。
关键是代价。如果不考虑代价,那么每个项目团队都会去做这件事情。只是大家都不是生活在真空里面。就像robbin这次的javaeye2.0之旅一样。这里面有平衡点,所以才会有这个话题。
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
robbin,那是不是可以认为这样的工作方式对开发人员的素养和开发习惯都有比较高的要求?你能不能推荐一些介绍如何采用feature驱动的方式进行团队协作开发的资料?
exception specification 可以是类型的一部分的。
其实静态类型语言,除了性能方面的考量之外,最大的优势就是可以提供静态类型安全,编译器可以检查你的每一个函数调用是不是书写了正确的名字,是不是提供了正确类型的参数。这样一个系统,配合自定义类型的功能,可以让很多错误(比许多人想象的要多)在编译时就能被发现和定位。
类型一直是个有趣而富有争议的话题:一方面静态语言在动态配置,Agile开发,DSL的浪潮中显得有些力不从心;另一方面有些底层系统的开发者认为现在的强类型静态语言的类型检查还不够'强', 比如Tim Sweeny(Unreal 3D引擎开发者)在The Next Mainstream Programming Language的演讲中问大家如下的C++代码可能会有什么问题:
答案请看演讲稿第29页。
你这段代码是 C# 的 …………
exception specification 可以是类型的一部分的。
其实静态类型语言,除了性能方面的考量之外,最大的优势就是可以提供静态类型安全,编译器可以检查你的每一个函数调用是不是书写了正确的名字,是不是提供了正确类型的参数。这样一个系统,配合自定义类型的功能,可以让很多错误(比许多人想象的要多)在编译时就能被发现和定位。
类型一直是个有趣而富有争议的话题:一方面静态语言在动态配置,Agile开发,DSL的浪潮中显得有些力不从心;另一方面有些底层系统的开发者认为现在的强类型静态语言的类型检查还不够'强', 比如Tim Sweeny(Unreal 3D引擎开发者)在The Next Mainstream Programming Language的演讲中问大家如下的C++代码可能会有什么问题:
答案请看演讲稿第29页。
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
单元测试覆盖到这些语句很难么?实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本。
再说逃离单元测试的覆盖值得那么沾沾自喜么?logger为null是编译器能检查出来的?
另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到!
但是单元测试给我们创造最多的机会来发现错误,而TDD给我们更多利用单元测试的机会。
关于getter/setter类方法的测试,其实有两个意思。
一个是定义方的测试,只有强迫症才会在定义方测试。
另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。
而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问.
http://www.iteye.com/topic/33890
引用
是像Java或者C#这样强类型的准静态语言在实现复杂的业务逻辑、开发大型商业系统、以及那些生命周期很长的应用中也有着非常强的优势
这是一个存在于大家心里常识了。我承认我自己在潜意识里面也觉得静态强类型语言适合开发复杂,大型系统。而弱类型脚本语言不适合开发太复杂,太大型的项目。但是在参与这个讨论过程中,我突然开始置疑这个观点,事实究竟是不是这样的呢?
先定义一下标准:
强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#
弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
引用
观点一:静态类型语言因为类型强制声明,所以IDE可以做到很好的代码感知能力,因为有IDE的撑腰,所以开发大型系统,复杂系统比较有保障。
对于像Java来说,IDEA/Eclipse确实在代码感知能力上面已经非常强了,这无疑能够增加对大型系统复杂系统的掌控能力。但是除了Java拥有这么强的IDE武器之外,似乎其他语言从来没有这么强的IDE。C#的Visual Studio在GUI开发方面和Wizard方面很强,但是代码感知能力上和Eclipse差的不是一点半点。至于Visual C++根本就是一个编译器而已,羞于提及Visual这个字眼。更不要说那么多C/C++开发人员都是操起vi吭哧吭哧写了几十万行代码呢。特别是像Linux Kernel这种几百万行代码,也就是用vi写出来的阿,够复杂,够大型,够长生命周期的吧。
引用
观点二:静态语言相对比较封闭的特点,使得第三方开发包对代码的侵害性可以降到很低。动态语言在这点上表现的就比较差,我想大家都有过从网上下载某个JS包,然后放到项目代码里发生冲突的经历
也就是说静态类型语言可以保障package的命名空间分割,从而避免命名冲突,代码的良好隔离性。但是这个观点也缺乏说服力。
静态类型语言中C,VB都缺乏良好的命名空间分割,容易产生冲突,但是并没有影响他们做出来的系统就不够大,不够复杂。
而Visual C++开发的DLL版本冲突也是臭名昭著的,似乎C++的命名空间没有给它带来很大的帮助。
而动态类型语言中Ruby/Python/Perl都有比较好的命名空间,特别是Python和Perl,例如CPAN上面的第三方库成吨成吨的,也从来没有听说什么冲突的问题。
诚然像PHP,JavaScript这样缺乏命名空间的动态语言很容易出现问题,但是这似乎是因为他们缺乏OO机制导致的,而不是因为他们动态类型导致的吧?
说到大型系统,复杂业务逻辑系统,Google公司很多东西都是用python开发的,这也证明了动态类型语言并非不能做大型的复杂的系统。其实我个人认为:
动态类型语言,特别是高级动态类型语言,反而能够让人们不需要分心去考虑程序编程问题,而集中精力思考业务逻辑实现,即思考过程即实现过程,用DSL描述问题的过程就是编程的过程,这方面像Unix Shell,ruby,SQL,甚至PHP都是相应领域当之无愧的DSL语言。而显然静态类型语言基本都不满足这个要求。
那静态类型语言的优势究竟是什么呢?我认为就是执行效率非常高。所以但凡需要关注执行性能的地方就得用静态类型语言。其他方面似乎没有什么特别的优势。
评论
45 楼
robbin
2006-11-15
jack 写道
动态类型语言如果没有良好的IDE,调试器,并不合适初学人员使用.初学人员需要有外部工具来限制其不可预料的行为.静态语言有编译器存在,可以很大的限制初学者出错的可能性.有调试器,则可以明确定位错误发生位置.
动态语言大都时候都只有一个解释器,如果开发人员经验不够丰富,那么完全不能胜任开发工作的.
Java/C#这类语言,菜鸟和高手都能够完成同样的功能,就是所需时间不同而已.
能够给大量菜鸟使用,并可以堆出一个可以部署的项目,就是静态语言的优势了.
动态语言大都时候都只有一个解释器,如果开发人员经验不够丰富,那么完全不能胜任开发工作的.
Java/C#这类语言,菜鸟和高手都能够完成同样的功能,就是所需时间不同而已.
能够给大量菜鸟使用,并可以堆出一个可以部署的项目,就是静态语言的优势了.
Jack同学,你这想法真的大错而特错了。PHP就是因为是动态语言,就是因为不需要复杂的IDE,不需要调试器,只有一个解释器,所以菜鸟才能够很快上手,所以互联网70%的网站都是PHP开发的。不瞒你说,现在也有很多很强的PHP IDE出来了,例如Zend Studio之类,但是我还是觉得UltraEdit好用,为啥?简单呗!
互联网网上真正用静态类型语言开发的网站所占的比例还不到20%,而超过80%的都是脚本语言开发的。
我用Eclipse已经有三年了,但是Eclipse的很多功能我到现在都没有掌握,调试器也只不过会最基本的功能而已。你说那么普遍的字符串拼接SQL的错误,Java里面还不是一大把吗?难道Eclipse可以限制初学者不用?HTTP Session里面随便乱塞结果集Eclipse可以避免?数据库连接不关闭Eclipse可以编译检查出来?
这些web开发当中最容易犯的错误,反而是脚本语言不容易出现,为啥呢?因为脚本语言是进程模型,不需要关闭数据库连接,内存当做不保存Session,所以Session可以随便乱塞东西,SQL拼接都提供了很强的字符串检查和过滤机制。
这不是我说瞎话,我帮很多Java系统做过性能排查和调优的咨询,Java新手的不良编程系统破坏力是及其惊人的,而PHP新手很少会在这种事情上遇到困扰。
44 楼
hyf
2006-11-15
jack 写道
BirdGu 写道
编译器对程序员的帮助到底有多大,这个还是要应人而异的。编译器能查出来的很多都属于打字错误,拼写错误。对于robbin来说,即使没有编译器,检查这种错误也是小菜一碟。可是对于经验不是很丰富的程序员来说,情况恐怕就大大不同了。毕竟程序员经验方面差异的一个重要方面就是Debug能力和经验的差异。对高手来说仔细读上两遍程序就能发现的错误,对一些新手来说可能会花上一两小时,这种情况我在实际项目中碰到很多次了。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
本以为这没什么好争的,
IDE作用大,不只因为是菜鸟。
我想知道有那位高手做项目时有好的IDE不用的。
用rails提高了效率,所以rails好。用IDE也提高效率,怎么IDE的就没啥用了?
做到一次code完,一次编译通过已经是难能可贵了。
还不需要Debug,那简直是讲故事。
43 楼
charon
2006-11-15
引用
首先我没有扯“什么是TDD中的T这个冷饭”!
别介,下面这句话是你说得吧
引用
实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本
根据这话里的意思,只能说明你做的就不是TDD,所以没必要戴TDD这顶高帽。
前面已经说过,TDD中的测试指的是准黑盒的功能性测试,没办法顾及到语句覆盖率的(这个是覆盖的最低级的一层).
引用
robbin已经说了,ROR没有get set.
robbin是说过这句话,但是你好像没有说过啊。你说得只是单元测试要覆盖。没有说针对什么样的语言.
或者,你从来就没有编写过java代码,那也是个说法。
或者,你编写java程序的时候就可以漏过getter/setter的测试,那不就结了,和我的结论一样,就没语句覆盖的事情了。
引用
再说我针对的是你那个logger的例子,请不要跑题。
跑题了吗? 前贴已经明确说了. 对于logger为null的情况,本身就不应该在使用这个logger记录日志信息的地方判断. 你如果对这个说法有异议,请提出来。
引用
拜托,我说要打谁了么?我只是说工具和流程不能代替人!仔细读读好么?
别激动,没说你要打谁啊,只是说你说那句话的时候纯属自娱自乐.因为没有人否认你的观点.
但是你现在的后续解释就有问题了.如果你想通过
引用
另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到!
这句话来推导出
引用
工具和流程不能代替人
这个逻辑也太不靠谱了吧. 难道你认为人就可以做到让代码正确无误? 如果不是这么认为的,那前提和结论根本就没有联系.
引用
TDD的优劣每个人都有自己的看法,我只是表达我的意见。我不会把自己的看法强加给别人,我也没这个能力。
这个只是讨论而已.如果每个人都只是表达自己的意见而不愿意在讨论中深入,那开个论坛干吗?
我觉得在论坛上有非常重要的一点. 那就是,每个人都是写给观众看的.
42 楼
robbin
2006-11-15
floating 写道
robbin 写道
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
robbin,那是不是可以认为这样的工作方式对开发人员的素养和开发习惯都有比较高的要求?你能不能推荐一些介绍如何采用feature驱动的方式进行团队协作开发的资料?
像XP就是比较适合RoR的软件开发方法阿,先讨论userstory,制订userstory card,然后一个card一个card进行小步骤迭代实现。
其实我觉得XP对开发人员技术素质要求不高,但是像沟通能力,团队协作的习惯要求比较高。
41 楼
cookoo
2006-11-15
jack 写道
BirdGu 写道
编译器对程序员的帮助到底有多大,这个还是要应人而异的。编译器能查出来的很多都属于打字错误,拼写错误。对于robbin来说,即使没有编译器,检查这种错误也是小菜一碟。可是对于经验不是很丰富的程序员来说,情况恐怕就大大不同了。毕竟程序员经验方面差异的一个重要方面就是Debug能力和经验的差异。对高手来说仔细读上两遍程序就能发现的错误,对一些新手来说可能会花上一两小时,这种情况我在实际项目中碰到很多次了。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
code once, run everywhere? 新广告词?
也许比较好的折衷是Erlang那种动态语言+类型检查器。C这么容易出错,我们靠lint/splint也挺过来了。
40 楼
dongbin
2006-11-15
引用
dongbin 写道
但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),这个代价和能力不是多数人所愿意付出的。
难道又要开始扯什么是TDD中的T这个冷饭了么?
但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),这个代价和能力不是多数人所愿意付出的。
难道又要开始扯什么是TDD中的T这个冷饭了么?
首先我没有扯“什么是TDD中的T这个冷饭”!
其次,“但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),个代价和能力不是多数人所愿意付出的” 是谁得出的结论?
基于我个人的实践,我不敢苟同。
引用
拜托,难道你在写java程序的时候真的测试了getter/setter这类方法?如果是的,恭喜你.........
robbin已经说了,ROR没有get set. 再说我针对的是你那个logger的例子,请不要跑题。
引用
兄弟,没人说编译器还是单元测试能保证代码正确无误啊。没必要自己树个靶子自己打吧。
拜托,我说要打谁了么?我只是说工具和流程不能代替人!仔细读读好么?
引用
关键是代价。如果不考虑代价,那么每个项目团队都会去做这件事情。
TDD的优劣每个人都有自己的看法,我只是表达我的意见。我不会把自己的看法强加给别人,我也没这个能力。
39 楼
jack
2006-11-15
BirdGu 写道
编译器对程序员的帮助到底有多大,这个还是要应人而异的。编译器能查出来的很多都属于打字错误,拼写错误。对于robbin来说,即使没有编译器,检查这种错误也是小菜一碟。可是对于经验不是很丰富的程序员来说,情况恐怕就大大不同了。毕竟程序员经验方面差异的一个重要方面就是Debug能力和经验的差异。对高手来说仔细读上两遍程序就能发现的错误,对一些新手来说可能会花上一两小时,这种情况我在实际项目中碰到很多次了。
所以我也强调静态语言编译器对于初学人员的帮助. 如果是robbin这样的高手,说不定就已经能够做到,一次code完,一次编译过,到处运行不需要debug的程度了.
不过吗,世界上还是新手菜鸟多.
38 楼
BirdGu
2006-11-15
编译器对程序员的帮助到底有多大,这个还是要应人而异的。编译器能查出来的很多都属于打字错误,拼写错误。对于robbin来说,即使没有编译器,检查这种错误也是小菜一碟。可是对于经验不是很丰富的程序员来说,情况恐怕就大大不同了。毕竟程序员经验方面差异的一个重要方面就是Debug能力和经验的差异。对高手来说仔细读上两遍程序就能发现的错误,对一些新手来说可能会花上一两小时,这种情况我在实际项目中碰到很多次了。
37 楼
charon
2006-11-15
dongbin 写道
单元测试覆盖到这些语句很难么?实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本。
遵循TDD,就会在不知不觉中覆盖到所有代码?无语中....
严格的说,TDD中的测试做的是准黑盒的功能性测试,而不是白盒的结构性测试。怎么可能起到覆盖所有代码的作用?
从测试本身来说,单元测试能做的比TDD中所谓的测试要细化得多。但是要做到语句覆盖以上的覆盖率(前面有个弱条件组合覆盖的例子),这个代价和能力不是多数人所愿意付出的。
难道又要开始炒什么是TDD中的T这个冷饭了么?
引用
再说逃离单元测试的覆盖值得那么沾沾自喜么?logger为null是编译器能检查出来的?
拜托,难道你在写java程序的时候真的测试了getter/setter这类方法?如果是的,恭喜你.........
如果不是,赶紧去补上............
至于logger为null,有两种情况,编译器能够检查出来logger未初始化就使用的错误(当然,如果必要,人为设置为null也可以骗过编译器)。
另一种情况,logger被在语义上合理初始化了,但是全局logger初始化的时候出错,这个时候,出错的是这个初始化的地方,正确的捕获位置应当在调用初始化的点,难道需要推迟到在使用logger来记录信息的位置来捕获? 在前面已经说了,这类logger语句中的错误,基本上不应该在此处被捕获。里面的隐含意义是:如果在初始化失败点被捕获,还有补救的可能,但是在日志记录点被捕获,基本就88吧。兄弟我看了那么多年程序,还真没看到过给logger.xxx语句套上try/catch的。而如果因为logger语句可能的问题而给整段代码套try/catch,那就是最愚蠢的做法了,一死全挺,而且程序死在次要功能上,哭都没地方哭。
引用
另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到!
兄弟,没人说编译器还是单元测试能保证代码正确无误啊。没必要自己树个靶子自己打吧。
引用
但是单元测试给我们创造最多的机会来发现错误,而TDD给我们更多利用单元测试的机会。
关键是代价。如果不考虑代价,那么每个项目团队都会去做这件事情。只是大家都不是生活在真空里面。就像robbin这次的javaeye2.0之旅一样。这里面有平衡点,所以才会有这个话题。
36 楼
jack
2006-11-15
动态类型语言如果没有良好的IDE,调试器,并不合适初学人员使用.初学人员需要有外部工具来限制其不可预料的行为.静态语言有编译器存在,可以很大的限制初学者出错的可能性.有调试器,则可以明确定位错误发生位置.
动态语言大都时候都只有一个解释器,如果开发人员经验不够丰富,那么完全不能胜任开发工作的.
Java/C#这类语言,菜鸟和高手都能够完成同样的功能,就是所需时间不同而已.
能够给大量菜鸟使用,并可以堆出一个可以部署的项目,就是静态语言的优势了.
动态语言大都时候都只有一个解释器,如果开发人员经验不够丰富,那么完全不能胜任开发工作的.
Java/C#这类语言,菜鸟和高手都能够完成同样的功能,就是所需时间不同而已.
能够给大量菜鸟使用,并可以堆出一个可以部署的项目,就是静态语言的优势了.
35 楼
floating
2006-11-15
robbin 写道
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
robbin,那是不是可以认为这样的工作方式对开发人员的素养和开发习惯都有比较高的要求?你能不能推荐一些介绍如何采用feature驱动的方式进行团队协作开发的资料?
34 楼
cookoo
2006-11-15
oops, 确实是C#的,好记性不如烂笔头555
33 楼
Elminster
2006-11-15
cookoo 写道
Elminster 写道
exception specification 可以是类型的一部分的。
其实静态类型语言,除了性能方面的考量之外,最大的优势就是可以提供静态类型安全,编译器可以检查你的每一个函数调用是不是书写了正确的名字,是不是提供了正确类型的参数。这样一个系统,配合自定义类型的功能,可以让很多错误(比许多人想象的要多)在编译时就能被发现和定位。
类型一直是个有趣而富有争议的话题:一方面静态语言在动态配置,Agile开发,DSL的浪潮中显得有些力不从心;另一方面有些底层系统的开发者认为现在的强类型静态语言的类型检查还不够'强', 比如Tim Sweeny(Unreal 3D引擎开发者)在The Next Mainstream Programming Language的演讲中问大家如下的C++代码可能会有什么问题:
Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m) { Vertex[] Result = new Vertex[Indices.length]; for(int i=0; i<Indices.length; i++) Result[i] = Transform(m,Vertices[Indices[i]]); return Result; };
答案请看演讲稿第29页。
你这段代码是 C# 的 …………
32 楼
cookoo
2006-11-15
Elminster 写道
exception specification 可以是类型的一部分的。
其实静态类型语言,除了性能方面的考量之外,最大的优势就是可以提供静态类型安全,编译器可以检查你的每一个函数调用是不是书写了正确的名字,是不是提供了正确类型的参数。这样一个系统,配合自定义类型的功能,可以让很多错误(比许多人想象的要多)在编译时就能被发现和定位。
类型一直是个有趣而富有争议的话题:一方面静态语言在动态配置,Agile开发,DSL的浪潮中显得有些力不从心;另一方面有些底层系统的开发者认为现在的强类型静态语言的类型检查还不够'强', 比如Tim Sweeny(Unreal 3D引擎开发者)在The Next Mainstream Programming Language的演讲中问大家如下的C++代码可能会有什么问题:
Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m) { Vertex[] Result = new Vertex[Indices.length]; for(int i=0; i<Indices.length; i++) Result[i] = Transform(m,Vertices[Indices[i]]); return Result; };
答案请看演讲稿第29页。
31 楼
tenyears
2006-11-14
高级动态语言的一个优势就是开发速度快,容易部署。
而缺点就是它们在某些方面很擅长,但不是所有领域。
我们不可能用Python和Ruby写一个Eclipse出来,也不能写一个VS2005出来。GUI是高级动态语言的其中一个缺陷吧(虽然也有一些GUI库)。
值得关注的是可以在Eclipse/VS2005上开发调试Python/PHP/Ruby代码,而反过来却不能。
而缺点就是它们在某些方面很擅长,但不是所有领域。
我们不可能用Python和Ruby写一个Eclipse出来,也不能写一个VS2005出来。GUI是高级动态语言的其中一个缺陷吧(虽然也有一些GUI库)。
值得关注的是可以在Eclipse/VS2005上开发调试Python/PHP/Ruby代码,而反过来却不能。
30 楼
robbin
2006-11-14
floating 写道
robbin,你在开发JavaEey时有没有做一些严格的建模工作?比如现在重要的class是不是基本上在设计阶段都考虑到了?还是你认为用RoR就应该遵循RoR提倡的Agile方式进行开发?
没有,边开发边设计,一边添加表上去。RoR本身也有比较强的DataBase Migration功能,强调了数据库表设计的敏捷化。
RoR就是feature驱动的,我觉得比现在主流的工业语言来说,更加贴近用户需求,更加强调反馈速度,迭代次数。这和现在主流工业语言的架构驱动确实感觉上很不一样。
29 楼
huangyiiiiii
2006-11-14
那只剩下一个区别了:c/c++可以访问底层,效率也高很多!java/c# 之流完全就淘汰了!
28 楼
dongbin
2006-11-14
引用
robbin 写道
to charon:
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢?
关于getter/setter类方法的测试,其实有两个意思。
一个是定义方的测试,只有强迫症才会在定义方测试。
另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。
而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问.
to charon:
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢?
关于getter/setter类方法的测试,其实有两个意思。
一个是定义方的测试,只有强迫症才会在定义方测试。
另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。
而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问.
单元测试覆盖到这些语句很难么?实践中遵循TDD,就会在不知不觉中覆盖到所有代码。我根本感觉不到额外的成本。
再说逃离单元测试的覆盖值得那么沾沾自喜么?logger为null是编译器能检查出来的?
另外,无论是编译器还是单元测试都不能保证代码正确无误--世界上没有任何方法或者技术可以做到!
但是单元测试给我们创造最多的机会来发现错误,而TDD给我们更多利用单元测试的机会。
27 楼
treenode
2006-11-14
动态语言缺乏编译检查,的确是一个问题,不过我觉得这个问题并不像上面说的那么严重。比起其他类型的错误如逻辑错误、设计错误、并发错误,语法错误实在是太容易检查和排除了,通常只要发生过一次,几分钟就可以定位并消除,比其他类型的错误动辄要几小时甚至几天来debug,根本不可同日而语。
我在开始写脚本的头一个星期,三天两头出现语法错误,导致程序崩溃,一个月以后基本上就没有了。就是出现错误,也很快就能发现。现在的脚本编辑器如pythonwin和kodomo已经能够显示语法提示,要写出没有或者很少语法错误的脚本,比过去已经容易多了。
要保证整个程序不会挂掉也容易,在高层模块加一个try/catch就够了,至少你的程序不会因此垮掉。
编译检查虽然好,但是它的局限也是很明显的,只要涉及任何动态特征——强制类型转换、动态代理、反射....它很快就起不上作用了。像Hibernate或者Spring这类高度依赖配置的框架,如果你在xml里敲错了一个字母,编译器检查又能帮什么忙呢?
我在开始写脚本的头一个星期,三天两头出现语法错误,导致程序崩溃,一个月以后基本上就没有了。就是出现错误,也很快就能发现。现在的脚本编辑器如pythonwin和kodomo已经能够显示语法提示,要写出没有或者很少语法错误的脚本,比过去已经容易多了。
要保证整个程序不会挂掉也容易,在高层模块加一个try/catch就够了,至少你的程序不会因此垮掉。
编译检查虽然好,但是它的局限也是很明显的,只要涉及任何动态特征——强制类型转换、动态代理、反射....它很快就起不上作用了。像Hibernate或者Spring这类高度依赖配置的框架,如果你在xml里敲错了一个字母,编译器检查又能帮什么忙呢?
26 楼
charon
2006-11-14
robbin 写道
to charon:
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢?
ruby on rails根本就没有getter/setter方法,你还有啥好测试的呢?
关于getter/setter类方法的测试,其实有两个意思。
一个是定义方的测试,只有强迫症才会在定义方测试。
另一个是调用方的测试,java中getter/setter只是属性访问方式的封装,在调用这类方法时,写完了通过编译就算ok了。
而在动态语言中,对属性访问的语句都必须用测试流一边。最大的好处是消除笔误和未赋值访问.
发表评论
-
WebObjects的来龙去脉
2012-06-08 15:30 7616在知乎上回答的一个问题:http://www.zhihu.co ... -
缓存技术浅谈
2010-09-24 18:08 21809有我在两年前写的一个培训的ppt,是介绍缓存知识的。有兴趣的可 ... -
对领域模型实现的总结性观点
2008-11-30 15:16 19561陶文发起的对领域模型 ... -
发现JBoss Seam很棒呀!有用Seam做过项目的吗?
2008-07-06 20:56 30328上周去见了一个朋友Mark,他应邀在Red Hat的研讨会上面 ... -
Spring Application Platform - SpringSource的应用服务器发布
2008-05-05 17:04 68942008年的5.1劳动节,Spring ... -
Warp framework - 一个相当有前途的Java轻量级Web开发框架
2008-03-06 15:24 22568Warp framework 是最近刚刚 ... -
Google Android会成为手机领域的微软Windows吗?
2007-11-16 17:23 9644Google gPhone手机的传言已经沸沸扬扬好几个月了,然 ... -
Java已经过时了吗?
2007-07-02 15:43 59723在四年以前,当我开始 ... -
Java开源框架发展的遐想
2007-05-23 00:04 34812上周末在杭州网侠大会做演讲的时候,我说:Java开源框架的革命 ... -
漫谈应用缓存的命中率问题
2007-05-09 14:19 26465这篇文章源自于: http://www.iteye.com/ ... -
为什么ORM性能比iBATIS好?
2007-05-06 11:16 34523缓存是有很多层次的,有web server前端缓存,有动态页面 ... -
点评Grails vs RoR
2007-03-30 17:49 8285Grails的革新和RoR相比,非常不彻底,很多地方兼容Jav ... -
缓存简述
2007-03-30 09:55 12263缓存实现的层面有很多: 1、对象缓存 由ORM框架提供,透明 ... -
JRuby0.9.8,正式宣布支持ruby on rails
2007-03-07 10:35 15668http://jruby.codehaus.org/ 自从S ... -
domain model的延伸讨论
2007-03-03 01:17 40711domain model,又称为领域模型,是Java企业应用讨 ... -
可以开始用Struts2.0了
2007-02-27 14:56 56102http://struts.apache.org/ Apac ... -
Google Guice - 比Spring快100倍的IoC容器
2007-02-27 14:46 58239http://code.google.com/p/google ... -
Spring2.0和EJB3.0随谈
2007-02-08 14:26 18464Spring自从2003年发布以来 ... -
Java程序员的推荐阅读书籍
2007-02-07 20:12 101365《Java程序员的推荐阅读 ... -
应该如何正确使用Quartz
2006-12-27 11:40 34234对于Web容器来说,最忌讳应用程序私自启动线程,自行进行线程调 ...
相关推荐
- **C 和 C++**:尽管 C 和 C++ 被认为是静态类型语言,但在某些情况下它们表现出了弱类型行为。例如,可以直接将整型变量与字符变量相加,而无需显式类型转换。 - **Perl 和 PHP**:这两种语言都是典型的弱类型语言...
静态类型语言要求在编译时声明变量类型,这有助于防止运行时类型错误,提高代码的稳定性和性能。 3. **浏览器内的编译和执行**:在浏览器内完成编译和执行可以减少对服务器的依赖,提高用户体验,因为用户无需等待...
Ravi编程语言是一种基于Lua 5.3的衍生语言,其设计目的是在保留Lua的简洁性和易用性的同时,引入了有限的可选静态类型。这使得Ravi在某些方面比纯动态类型的Lua更适合大型项目或性能敏感的应用,因为静态类型可以...
在IT行业中,静态页面与动态页面是两种常见的网页类型。静态页面是由HTML、CSS和JavaScript等静态文件组成的,内容在服务器端创建后直接发送到客户端,而动态页面则是在用户请求时由服务器端的脚本(如PHP、ASP、JSP...
**什么是静态类型检查?** 静态类型检查是在程序执行前进行的一种分析,它通过检查源代码中的类型声明来发现潜在的类型错误。与动态类型检查(Python默认的类型检查方式)不同,动态类型检查是在运行时进行的,这...
cpp-Empirical是一种专门针对时间序列分析的语言,它在C++的基础上构建,提供了静态类型的DataFrame数据结构。这个框架的设计目标是为科学家、工程师和分析师提供一个高效且易于使用的工具,以便处理和理解时间相关...
Kotlin编程语言,作为近年来备受关注的开源静态类型编程语言,已经在软件开发领域崭露头角。它由著名软件公司JetBrains发起,并且得到了全球开发者社区的广泛支持和贡献。Kotlin的设计理念旨在提高开发效率,降低...
JetBrains Kotlin ,一种开源的静态类型编程语言,由 JetBrains 和开源贡献者支持和开发,支持多平台编程是 Kotlin 的主要优势之一。它减少了为不同平台编写和维护相同代码所花费的时间 ,同时保留了本机编程的灵活性...
- **静态类型**:作为一种静态类型语言,Kotlin在编译阶段就进行了严格的类型检查,这有助于早期发现错误并提高代码质量。 - **类型推断**:Kotlin能够根据上下文自动推断变量的类型,这减少了显式类型声明的需求...
这个主题通常涉及广泛,包括静态类型语言和动态类型语言的对比,编译型语言与解释型语言的区别,以及各自在性能、开发效率、可维护性等方面的表现。 描述中的“NULL”表明没有提供具体的描述,但我们可以从常见的...
Java平台的多语言混合编程是指在Java虚拟机(JVM)上运行多种语言,包括静态类型语言和动态类型语言、命令式语言和声明式语言等。这种混合编程方式可以充分发挥Java平台的优势,实现跨平台、跨语言的开发。 Java...
静态页面生成通常分为两种类型:预渲染(Prerendering)和按需生成(On-Demand Generation)。 1. 预渲染:在项目构建阶段,静态页面生成器会遍历所有路由,根据模板和数据生成对应的HTML文件。这些文件会被上传到...
在IT行业中,动态网站与静态网站是两种常见的网页类型。动态网站主要依赖服务器端脚本,如ASP(Active Server Pages),来实时生成内容并交互,而静态网站则是预先编译好的HTML页面,直接由浏览器解释执行。后台ASP...
Python的语法较为宽松,支持动态类型,而C++则采用了静态类型系统,要求开发者在编写代码时明确指定类型。 2. **应用领域**:Python因其简单易学和丰富的库支持,在数据科学、机器学习、Web开发等领域受到欢迎。而...
4. **静态类型检查**:与动态类型语言不同,静态类型检查是在程序运行前进行的。通过这种方式,可以在代码执行前发现类型错误,避免运行时出错。Python本身是动态类型的,但PEP 484引入了对静态类型的支持,使得...
静态类型语言(如C++、Java)在编译时就确定了变量的类型,这种强制性类型检查可以在早期发现错误,提高代码安全性,并为编译器优化提供信息。相反,动态类型语言(如Python、JavaScript)在运行时才确定变量类型,...
一、静态页面的优势 1. **快速加载**:静态页面的内容在用户请求时不需要通过服务器处理,直接由浏览器解析,这使得页面加载速度更快,对于旅行者来说,快速获取信息是非常关键的。 2. **低维护成本**:静态页面的...
4. 静态类型:Go 是静态类型的,这在编译时就能发现类型错误,提高了代码的可靠性。 5. 简洁明了:Go 语言的语法简洁,易于学习和使用,减少了理解成本。 然而,Go 语言也有其不足: 1. 生态系统不成熟:相比于 ...
在Java编程语言中,静态方法是一种特殊类型的方法,它与类相关联,而不是与类的实例相关联。静态方法在类加载时就会被加载到内存中,因此它们可以在没有创建对象的情况下被调用。静态方法的继承和重写是面向对象编程...
在IT行业中,静态页面是一种常见的网页设计类型,它主要用于创建简单、快速加载且内容不需频繁更新的网站。"图片展示静态模板"标题暗示我们这里关注的是一个专门用于展示图片的静态网页模板,这种模板通常包含精心...