瞎扯淡 疑 Google 员工把 8w 行 Python 项目用 4w 行 Java 重写了

cassiuschen · December 08, 2013 · Last by jtianling replied at September 15, 2015 · 23041 hits

Rails 项目后期迁移到其他语言的倒也很多,但没觉得这是动态语言的劣势吧…… 以下原帖:

发信人:daluobu (阿土仔), 信区:Python 标 题:终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Fri Dec 6 08:10:26 2013), 转信

在噩梦般地维护了一年多一个 8 万多行的 Python 程序之后,终于争取到机会把这个破烂玩意用 Java 重写了一遍,大概是 4 万行 Java 左右。说说效果吧:

  1. 从过去平均每周 down 一次,到现在连续运转近半年只 down 过一次。
  2. 节省超过 80% 的 cpu 和内存
  3. 代码多了很多功能,过去无数因为系统太复杂无法实现的功能现在都能简单清爽地实现了。
  4. 单元测试真管用了,不是过去那种把代码反过来写一遍的滥用 mock 了。 前后代码都是同一个 team 写的,写代码的人都不是菜鸟(顶级公司的核心团队)区别只有语言和几年的经验积累。

总结一句话就是:动态语言滥用起来真是可怕

珍惜生命,远离 Python。

※ 来源:·水木社区 http://newsmth.netFROM:·[ 216.239.45.*]

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Fri Dec 6 08:24:55 2013), 转信

刚开始写的时候以为就是随便 hack 一个小系统临时用用,结果慢慢发展到成为关键系统,负载巨大,而且还对宕机越来越敏感,导致不得不用 Java 重写。重写也不是那么简单的过程,半年多时间里面一个模块一个模块地替换,整个系统还不能停转一分钟,像是给一架飞行中的飞机换引擎。

同样的故事在别的公司肯定也发生过好多次,写一个小东西玩玩结果变成了关键系统。我觉得我们团队的问题是几年前过分迷信 Python,错过了在系统还不太复杂的时候重写的机会。

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Fri Dec 6 13:42:31 2013), 转信

原帖说的是一个 10 个人团队的故事,不是他自己。信与不信其实并不太重要,我发这个帖子也是纪念一下这个美梦成真的项目。如果有人有共鸣,那就已经很好了。

过去公司里面也是有不少迷信 Python 的人,重写系统的想法我在组里提了很多次,终于在一个 Python 大粉丝离开之后才得以实现。现在随着某 Python 之父的离开,公司里面粉 Python 的人也越来越少了。而且事实证明,那个 Python 之父带的项目(不是我们这个,比我们这个规模要大一些),用 Java 重写之后,不论功能还是性能还是新功能,也都明显好了很多,和我们组的经验相当吻合。

我觉得代码行数的节省也在于新系统更严谨的设计。Java 鼓励精密的接口设计和简洁的代码关系,再加上 Dependency Injection,代码的复用程度很高。Python 完全没有接口的概念,一切类都是胡乱写,还可以动态增加新成员,导致代码复用的难度相当大,不修改地复用一个类还不引入 bug 简直是奇迹。

※ 来源:·水木社区 http://newsmth.netFROM:·[ 216.239.45.*]

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 00:48:05 2013), 转信

这个项目里面,重构是一直在进行的,在过去的八年里面,用 Python 大规模地重构也发生过好几次。

决定用 Java 重写是很艰难的,不是某个人拍脑袋的决定。放弃 Python 主要是因为它的代码可维护性比较差,缺乏编译器检查,动态语言特性导致模块间过渡耦合,缺乏性能分析工具,内存管理机制低效,多线程性能很差。这些都是一个持续维护很多年的高负载应用所必须的。

Linter 能做的事情很有限,公司代码管理系统早就是不过 lint 不能 submit。code review 也不能解决问题,因为团队里面每一个人对于系统设计和语言特性是否滥用理解程度都不同。

争论是否能够通过管理来解决语言本身缺陷其实是没意义的,因为我们碰见的是实实在在的语言缺陷问题,就应该用最直接的解决方案。

“Python 很好,只是你们这些外行不会用”,这是我听到的最多的所谓 Pythonic 人的论调。事实是 Python 作者自己亲自带领的那个项目也是一塌糊涂。他们遇到的最主要问题就是可维护性低和性能差。世界上有没有人比 Python 作者本人更 Pythonic?如果他自己的项目都不行,谁能做得更好?

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 01:30:35 2013), 转信

如果一个语言比另外一个差 1000 倍,那就是很大的问题了,随便写两行 code 都可能成为性能瓶颈。Python 又恰好缺乏性能分析和优化工具,导致出了性能问题都不知道在哪儿。BTW,1000 倍这个数据是有依据的。

接口上所谓的冗余其实是提高程序可维护性的关键。人脑容量有限,所以必须用电脑辅助人脑进行接口使用正确性的检查。强制要求程序员写强类型的接口也是一种强迫程序员对正确的设计进行思考的过程。结果导致的就是强类型语言可维护性更好。Openstack 只有 1.4M 和 3 年历史,用 c/c++/Java 写的大型软件都是复杂几个数量级,而且维护几十年。Python 程序的问题之一就是“腐烂”得很快,程序刚写好的时候看起来很简洁,一旦开始维护就快速地变成一堆乱七八糟的东西,动态语言代码腐烂速度远远超过强类型语言。 如果 Python 作者本人带领的团队都写不出可维护的 Python 代码,谁能?

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 01:50:35 2013), 转信

Guido 搞的那个 code review 系统就是我说的那个维护不了的系统,最后的结果就是用 Java 重写了。新系统比旧系统好用很多,而且还持续有新功能上线。那个项目组有一个在公司内部流传很广的文章,说为什么需要用 Java 重写,并且结论是 Python 只适合写 100 行以内的小脚本。我刚才试了找这个文章有没有外网可以访问的版本,但是没找到。

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 02:25:23 2013), 转信

如果用一个语言开发出可维护的代码需要的能力超过了 Google 能招聘到程序员的平均水平,我认为这个语言就不是一个可以用来开发可维护代码的语言。创造出一个不可维护的语言很容易,汇编,Basic 以及大批的早期编程语言都是这种。创造出可以让普通程序员也可以维护的语言才是更困难的,只有少数语言做到了,C 和 Java 是,C++ 都不能算是很成功。

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 02:48:32 2013), 转信

你几乎都说反了,Google 非常重视代码的可维护性,扩展性几乎是在项目一开始就必须考虑的问题,Google 对软件工程实践的重视和深度是我所知道的公司里面最高的。不知道你说的管理是什么意思,但是 Google 有强制性的代码规范,有强制性的 designreview。Python 的很多“高级”特性已经在编程规范里面禁用了,但是有些特性是没法禁用的,比方所有对象 member 都是 public,比方函数参数没有类型。就是这些很基本的东西带来的可维护性问题。

越是水平高的程序员越是会遵守编程规范和软件工程实践。至少在我们这种产品 team 里面大家是相当重视代码质量和设计质量的。这也是为什么我们舍得投入那么多把一个不好的系统重写。

【在 Alassius (饿了索食) 的大作中提到:】

问题是这种不可维护性恐怕正是贵司能招聘到的这种平均水平造成的。智商高,技术至上,写代码怎么聪明怎么来,不重视维护,不重视扩展性(直到太迟的时候),不重视软件工程,不重视管理。普通程序员如果有好的资深码农引导,早早地被告知不要滥用语言的灵活性,倒未必会有这些问题。聪明的程序员你这样跟他说他还看不起你。

发信人:daluobu (阿土仔), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 03:21:05 2013), 转信

意思就是:任何流程,任何规范,任何 review,任何代码检查工具,都阻止不了程序员缓慢地一点一点地滥用语言特性,也阻止不了一个软件代码自身的腐败。Python 本身鼓励滥用 Mock 因为没有不用 mock 就可以方便写 unit test 的测试工具。Python 还鼓励不定义清晰的类接口和类关系,如果你写了一个接口继承,就会有 Python 大牛跳出来说你不 Pythonic。系统复杂性在大型软件中是不可避免的,但是如果我们可以付出一些写 code 的时候的小小冗余,带来长期的代码可维护性改善,那就是值得的。Java 不是完美的,用 Java 一样可以写出不可维护的代码,但是 Java 至少比 Python 在这方面强很多。我们的经验证实了这点,信与不信就是看官的事了。

发信人:YABC (Yet Another BBS Client), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 10:26:33 2013), 转信

难得这么热烈的讨论,可是争论语言优劣没结果。

希望楼主再爆料点。这个大粉丝说的就是 Guido 了吧?这套系统说的就是 Rietveld?Java 的版本说的是 Gerrit 吗?可是 Gerrit 不是早就有了吗?难道你们内部用的不是开源的 Gerrit?另外,GAE 的 Python 版本你们内部有什么评价呢,比起 Java 和 Go 的呢?也觉得质量不行吗?Guido 干得不爽才走了吗?谢谢。

我用过 Rietveld,是 Python 语言本身在用的 review 工具,感觉风格挺老旧的。还没见有别的项目用这个东西。

发信人:YABC (Yet Another BBS Client), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 10:41:11 2013), 转信

Gerrit 是这个项目的 Java 的 fork,很多大项目在用。从这点说 Guido 开创的这个 Python 项目算成功的。当然后面的自然会吸取前面的教训,做得更好是应该的。

发信人:iJava (简单美好), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 14:28:56 2013), 转信

这个帖子满精彩的,俺就 8 了一下:

楼长说的那个系统应该就是 Mondrain,从来没有开源的。这里有详细的介绍,包括对 g 公司的 code review process.

http://www.youtube.com/watch?v=sMql3Di4Kgc

发信人:yueq (yueq), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 16:09:34 2013), 转信

根据楼主的描述,是 Google 的内部 code review 工具:)。

发信人:yueq (yueq), 信区:Python 标 题:Re: 终于把一个 8 万行的 Python 程序用 Java 重写了 发信站:水木社区 (Sat Dec 7 16:15:16 2013), 转信

旧系统 Mondrian 新系统 Critique

如大家上所述,我觉得楼主对于 UT、OOP 的理解还有待加强。

(我也在 G 家某组用 PYTHON)

所以我开始学 Java 了 ...

#1 楼 @bhuztez 因为项目上规模了?

#2 楼 @cassiuschen 上规模还用 Java 是和自己过不去吧 ...

#3 楼 @bhuztez 但是静态真心好维护么…

java 计算,4 万行只是个非常小的小项目,还有一个 team 弄,G 社的钱真好赚...

#4 楼 @cassiuschen 静态类型也有不好维护的地方啊,你真以为 Java 是静态类型的?呵呵

#5 楼 @luikore 尽管只有 4 万行 Java,但是没说有多少行 XML 啊。

怎么说呢 0.0
个人感觉 摸索着写项目和高屋建瓴地写是有区别的

#8 楼 @sandtears 绝对正解! 不过动态语言少了编译时类型推断真的应该算是缺点。

#7 楼 @bhuztez 光 java 也很少... 夹沟师随便搭个骨架就 15 万行了

总结一句话就是:动态语言滥用起来真是可怕

的确可怕,超多重复的运算。

是不是 Python 水平太烂了呀,在互联网行业,要从语言上优化性能,那轮得到 Java 呢,怎么也是 C++ 级别的。我们公司把 Java 换成 Python 后,内存和 CPU 节省了不少,每天将近 20 亿的访问量一点都没问题。但是 Python 开发效率是 Java 没法比的。所以,还得仔细看下场合吧,什么样的业务用 Java,什么样的用 Python。

#12 楼 @zeeler 你们什么公司这么奇葩

#10 楼 @luikore 所以说明他们 Java 水平高啊

人生苦短,还是用 Python

奇怪,为什么不是换 Go 呢?

#13 楼 @bhuztez 互联网高并发环境下,谁是靠好的语言来保证性能的?都是靠好的架构,保证高的 cache 命中率或者静态化,其实大部分瓶颈都在数据库和 IO 上。一秒内几十万个用户都要把他们提交的信息写入你的数据库,光靠选择语言,用汇编都解决不了,必须要靠好的架构来解决。

聊各种语言性能差异都是扯淡,有这个时间做个性能测试再说. 系统性能有问题应该先检查代码的质量,把猪一样的队友造成的问题先解决掉。

如果一个语言比另外一个差 1000 倍,那就是很大的问题了,随便写两行 code 都可能成为性能瓶颈。Python 又恰好缺乏性能分析和优化工具,导致出了性能问题都不知道在哪儿。BTW,1000 倍这个数据是有依据的。

那看来 Python 水平确实不行了。

用 JRUBY 写代码量小于 2W 行。需要的功能都成 Gem 了,那还要写啊。

没有用 Java 做过什么事的又再黑 Java,笑一笑,飘过。。。

#12 楼 @zeeler 20 亿的访问,难道是豆某瓣?

这么一提起 JVM 我突然对 Scala 很感兴趣

java 还是自然有它的优势。ruby 这样的程序复杂了重构真是头疼的事情,到处搜索哪里被用到。正考虑做一部分 java 的替代,唯一就是 rails 被 cache 的对象如何在 java 这里获得。不知道 ruby 的序列化是否可以被 java 反序列化。

先把这句话呛死:"世界上有没有人比 Python 作者本人更 Pythonic",扯!每门语言的创始人就是使用这门语言最牛的人?瞎盲目崇拜,只能说它了解这门语言的底层确实够多,仅此而已。

说 python 比 java 耗内存基本认同。其他说半天没扯出来 python 到底弱在哪里,只能给原作者一句评价:你确实更善于用 java,而不是 python。down 不 down 跟语言关系大么?头贴都在说什么啊,就内存那条跟 python 有关系。

不好妄加揣测原作者的情况,我只知道,不管什么语言的,几乎所有新来的都嫌老系统乱 --- 程序员大都有这毛病。

"Python 完全没有接口的概念,一切类都是胡乱写,还可以动态增加新成员,导致代码复用的难度相当大",好不容易扯到 python 了,一切都是乱写... 嘿嘿,作者真凌乱了,有什么非得接口不可的 python 没有替代的倒是讨论讨论?

哎,说太多了...

看下来觉得和语言完全没啥关系,找个 python 团队好好重构下估计一样能达到效果。

我们公司的渣代码,一个累 2k 多行代码。。所以,不要看代码行数,

我在想那 4W 行 java 应该没包括配置的文件里的代码

我只能说 任何系统只要重写都会提高性能 完善接口 与新系统用得那门语言一点关系都没有

@zeeler "每天将近 20 亿的访问量一点都没问题". 整个系统都是 Python 做的吗?要是的话,那你们是世界上最牛或最有钱烧的公司了。

Ken 认为,代码总会以某种方式“腐烂”掉,即使没有做任何修改。而对于腐烂的代码,方法就是将其扔掉,重新写。 用 Java 新写的,以后也会一样。

在噩梦般地维护了一年多一个 4 万多行的 Java 程序之后,终于争取到机会把这个破烂玩意用 C 重写了一遍,大概是 2 万行 C 左右。说说效果吧:

  1. 从过去平均半年 down 一次,到现在连续运转近一年只 down 过一次。
  2. 节省超过 80% 的 cpu 和内存
  3. 速度快了一个数量级。
  4. 老板不敢解雇我了。 前后代码都是同一个 team 写的,写代码的人都不是菜鸟(顶级公司的核心团队)区别只有语言和几年的经验积累。

总结一句话就是:虚拟机语言滥用起来真是可怕

珍惜生命,远离 Java。

#34 楼 @niuniu4 你知道个大的系统每块都是 C 写的吗?

#32 楼 @edoc API 部分啊,监控等是 Python,几十台服务器,几个程序员就成最烧钱的公司了?有没有搞错,让阿里、腾讯、facebook 等这些公司的岂不是笑掉大牙啦,他们养了多少技术团队,用了多少服务器!另外,阿里把 java 虚拟机都重写了,现在淘宝网在用,性能等各方面肯定更优化了,而且自己定制的肯定方便向业务倾斜。但是。。。。。。有几个公司可以重写 java 虚拟机?

#24 楼 @small_fish__ 某一线网站移动端服务器就是 python 写的,但不是所有地方都是 python,内容管理系统还用了 ruby on rails,push 还用了 java,某些地方是 c,shell, awk 等等,不排斥某种语言,选择时只是考虑了某一方面的特长,比如有些地方既要开发效率高,又要性能足够等等。

#32 楼 @edoc 20 亿对于大型互联网公司不算啥吧……g 社光搜索就应该几百倍于 20 亿……而且我估计是 pv 不是浏览量……

觉得 java 这种语言重点在于设计,python/ruby 在持续的重构。 如果问题已知,需求已知,用 java 进行设计,自然设计一下会好不少。 敏捷开发很大程度上假定了,需求不确定,问题不确定这种情况(事实也应该如此。。。)。如果在这种情况下,瀑布流之类的,就不再适,因此要用 BDD 保证做正确的事,和 TDD,保证正确性。 无论是完整的 TDD,还是完整的敏捷开发,都要求持续性的重构(10 几行就可以重构一次)。 测试是为了让你不断折腾,测试覆盖的越好,你改代码改的越舒服,就算是红掉了,也很容易定位。

有个牛人说,legacy code 分两种,一种有测试的,一种是没测试的。我承认我跑题了。。。

@yfractal 正解 码农们回家养猪吧 嘿嘿

仔细的看了这篇文章,感觉和 ruby 社区关系不大,毕竟是 python 嘛,毕竟 ruby 世界的单元测试的基础设施要比 python 世界的好很多。但是里面又处处用"动态语言"一概而论,处处体现了题主对动态语言的不了解,毕竟这个世界的 Java 程序员最多了,他们有很强的话语权。其实每个人看到用其他语言写的程序时都狠不得用自己最熟悉的语言写一遍,这是常理,要理解。总结一下,观后感吧:

  1. 原来 google 这样的大公司也有很多不靠谱的项目和不靠谱的人。
  2. 动态语言在项目大了后,所带来的不好维护性,确实存在,这个不好维护性因为和静态语言有很多地方表现并不一致,所以解决方案也很不一样,所以如果有静态语言维护经验的程序员去维护动态语言的项目,他们,确实想死的心都有,所以想重写也很正常,是我,我也遭不住经常 down 机的折磨,整天提心吊胆的日子不好过啊。目前在很多地方,动态语言,不,就说 ruby 吧,是增加测试覆盖率来实现的,所以 ruby 世界里面各种 BDD,TDD 是很完善的,一个 Rspec 就甩出各种什么 Unit Test 好几条街了,简直就不是同一个时代的东西。
  3. 刚才说的是可测试性,现在来说可维护性,我天天做梦都期望:前一个程序员兄弟的代码,只需要我 config 一下就可以实现客户的需求。但是,你我随时都有可能成为那个最不靠谱的队友,动态语言威力无穷,有些特性确实不要滥用。比如 Rails 里面的 Model Hooks.
  4. 再次声明,这个世界上 Java 程序员的人数庞大,所以他们有强大的话语权,很多项目 2 句 Ruby 就能搞定的事情,非要被他们说成用 Java 更安全云云,最后搞来一个团队来做了一周。里面还有很多看了就恶心死人 JUnit 代码。所以很多时候,不是 Ruby,Python 做不了,而是确实招不到靠谱的 Ruby,Python 程序员,而 Java 程序员往往又不了解动态语言的世界是怎么玩的,他们要用他们世界的概念去套,但又发现套不上(唉,怎么没有依赖注入呢?),他们把这个玩具玩坏了,还非说这个玩具设计的不好。
  5. 原来 google 也有这么矫情的人。
  6. 没有一种语言是完美的,所以还是多了解一两种语言为好。

#31 楼 @iBachue 我只能说 任何系统只要重写都会提高性能 完善接口 与新系统用得那门语言一点关系都没有

看到这新闻的时候我第一反应也是这个

#36 楼 @zeeler 好吧,理解错误,只是内部 API 监控啊。不要提阿里,阿里的东西很烂,不过走了很久了,不知道现在怎么样了。

我觉得重写是很有优势的,你可以知道之前的代码瓶颈在哪里,和语言没关系,我相信如果那个人肯花时间用 python 重写,肯定能达到一样的效果,代码量肯定比 java 少。

#44 楼 @targetoyes 完全同意你的说话,同一个系统,同一批人,"区别只有语言和几年的经验积累"以后,用原来的语言,可能效果会更好,同时,用 Python 实现花费的时间也会比用 Java 实现花费的时间少。就像重构常常用的是同一种语言,一般也是往好的方向发展的。

动态语言本身就有动态语言难以构建大规模系统的问题,这是为什么以 C 语言为代表的静态语言被创造出来,动态语言在静态语言占据编程领域很多年以后能再度崛起 (以 Python, Ruby 为代表), 是因为动态语言能更快的构建系统的优点加上新的完善单元测试的实践。 PS: 虽然我不同意作者的观点,但是我本人并不是个 Python 的爱好者,相对来说,我会更喜欢 Ruby, 但是这并不重要,要是说到语言的发展趋势,将来一定是写起来像动态语言一样方便,支持更好抽象特性 (抛弃和汇编能直接对译这种追求) 的静态语言的天下。

You need to Sign in before reply, if you don't have an account, please Sign up first.