如果静态类型的语言比动态类型的语言更加适合大项目,那么是否在一定规模和复杂度以下动态类型的语言更好?
程序员文章站
2022-04-28 16:30:58
...
首先,个人确实比较认可静态类型的语言更适合大项目。那么动态类型的语言在什么规模下更好呢(意思是在这个规模下不仅能完成而且比静态类型语言更合适)?比如Discuz、Wordpress、豆瓣用的是PHP、Python等语言,规模是十几万到几十万行不等,而我自己并没有参与过什么更大的项目,所以这方面认知不足。敬请各位指点。
----------
补充,在下对这个问题的困惑是阅读过Discuz和Wordpress的代码,感觉像一坨翔(当然可能因为我水平低),规模也就二三十万行。真无法想象更大的系统将是什么样子(比如豆瓣)。最突出的一个感觉是静态类型语言的项目容易grep而且有好用的、能够准确跳转到定义的IDE。
先说性能。PHP业界很有力的佐证是Facebook对PHP动态执行环境的摒弃与改造,对FB这个量级的公司是有意义的,它们不愁招不到人,也不愁招到的人驾驭不了一个自定义的编译运行时的长期迭代。一般团队是负担不起这个成本的,也没有必要,大多数Web后台只需要把数据库这一层优化好就没有什么瓶颈了。关于FB的这方面文章很多,我想不需要展开了。
安全。好像没什么证据能证明静态语言比动态语言更安全,安全最终还是取决于代码本身的质量,而静态或者动态并不决定代码质量,人决定代码质量。但是,静态语言有一个好处,能做静态分析,而动态语言要难得多,静态分析能通过一些手段提前审计代码本身的质量,所以非直接地提供了改善代码质量的途径。但大多数项目,这个好处远没有重要到可以牺牲开发效率。
比如写一组REST API,用PHP和Go,你能明显比较出来PHP或者动态开发语言的开发效率,对初、中级的开发团队尤其明显,如果用Go,碰到稍复杂的结构,不熟悉光是类型定义与转换就会费很多脑筋,而结果也并不比PHP代码质量高多少,即使Go编译出来的代码本身快很多,但无关,因为大型应用的瓶颈首先一定是数据库,离语言本身成为瓶颈还很远。
因为语言和其实现是可以独立的,所以上面所说的脚本解释器的优点并不能认为是动态语言的优点 首先表明立场,动态静态没有本质上的优劣,还是那句老话,合适的才是最好的。
要说清楚这个问题,先得弄清楚动态和静态类型到底是什么。
静态类型是指变量类型初始化后就不能改变,比如a初始化为int,那它就是int了,不能给它赋值一个字符串,并不是说一定得是“int a = 1”这种有标识符的才是静态类型,比如swift这种可以通过类型推倒来决定变量类型的也可以,所以本质是类型确定了就不能变。
动态类型说的是变量的类型跟着赋值的值来定,赋值int就是int,再赋值字符串就是字符串,是的,就是这样墙头草,两边倒,你说是啥就是傻。
我看前面有朋友说 动态类型和静态类型的本质区别不是规模,而在于测试。抱歉可能是我理解不对,测试方法,不管是单元测试、集成测试、系统测试等都和语言无关,动态类型和静态类型都有各自的实现方案,而且都久经检验,所以在我看来测试这个话题本身已经和语言没有关系了,也就谈不上是语言区别的本质了,并且我也了解到银行的部分定时批量脚本(跑批)还真就是用python实现的。
那动态和静态的区别到底给编程带来了什么样不一样的感受?首先,由于静态类型类型不可变,在写程序的时候避免了很多低级的错误,最常见的是先定义了一个变量是int类型的,然后后面代码很长忘记了,又定义了一个一样的变量,换成了字符串类型,最后需要用到int类型的变量,这样的话在不知情的情况下变量的类型已经发生变化了,最后使用的时候肯定会出错,然而静态类型这种情况不允许,所以就避免了,动态类型是允许这种情况的,所以出错了语法上找不到错误,排查起来很困难,如果再是int类型和string类型自动转换的话,情况就更糟了。
总结一下就是,静态类型里的语法错误在动态类型里编程了语义错误,排查起来难度比较大,所以可能给人造成动态类型不适合大规模项目的场景。但是上面说的问题更多是开发人员自己习惯不好,变量命名不好,函数可能很长,是可以通过编程规范来约束的。BUG永远是开发人员制造的,开发人员素质不行,用什么语言都白搭,会搞出一堆feature....所谓动态语言容易出问题,更多是开发人员为自己能力不够找借口,不值得效仿!
最后说说题主关心的规模和语言适配问题,我只能说题主多虑了,思维需要看远一点。什么叫大规模项目?淘宝算大吧!那淘宝整个系统是怎么样的?分布式!不是只用一种语言,不是只有一个系统!底层中间件基本是java,底层服务层也基本是java,上层也有nodejs、php,然而这些都不是一个项目,都是分拆成很多个项目来做的,每个项目的规模都不大,而且每个项目都可以用其它语言来编写(只要符合规范),淘宝内部也正在丰富编程语言的多样性。有的人可能会说,淘宝不正是从php迁移到了java么?是的,但是并不是因为动态和静态的,是因为性能和业务需求。需要做服务化,服务发现,还有一些底层存储,php搞这些效率低下,所以才换的,不是说是因为动态语言。
还是老一句,没有具体的指标,只看是否适合自己。架构与选型是技术向业务妥协的结果!
要说大项目,比如十多年前Erlang项目,AXD 301有大约200万行Erlang代码。而之前Ericsson妄图用C++开发同样的东西,没开发出来。这能不能说明动态类型比静态类型更适合大项目呢?
就是这样。 我前几天的微博。。
偶也,打完收工。。= =merge几十个changes..有按changelist的,有copy的,有临时branch里改的。。最后编译通过。。unittest通过。。然后果然就没什么问题了。这也就是静态类型语言。。这要是python。。呵呵。 准确性很重要的。使用动态语言很难保证准确。 动态语言比较适合字符串处理,或者说html文本处理而已。比如,做个网页抓取。如果用它写算法,就不行。 关于类型系统的作用,看 @雾雨魔理沙 的答案(以及同问题下很多其他答案)
http://www.zhihu.com/question/38378942/answer/84744046
--- 原答案 ---
并不是说“在一定规模和复杂度以下动态类型的语言更好”,而是说,在大多数情况下,上 Python 这种代码起步更快,如果只是希望快速解决一个问题或者跑一个简单 web 程序,用这些快速上手的东西上手做的代价更低。
应该把软件看作一个生物,每个模块是一个细胞。当这个软件代码不断“生长”后,细胞会变大,更会分裂成多个细胞,而且会演化成不同功能的细胞相互协作。细胞就是模块,而细胞的种类就是实现这个模块的语言。Web 用 Python 快速搭起来,性能关键的部分用 C / Fortran 写好,数据挖掘的部分直接上 Hadoop,都是太正常的复杂系统架构了。
p.s. PHP 这种为了单页内容设计的语言,写随便大点的项目写成一坨翔简直是应该的。
----------
补充,在下对这个问题的困惑是阅读过Discuz和Wordpress的代码,感觉像一坨翔(当然可能因为我水平低),规模也就二三十万行。真无法想象更大的系统将是什么样子(比如豆瓣)。最突出的一个感觉是静态类型语言的项目容易grep而且有好用的、能够准确跳转到定义的IDE。
回复内容:
我想说性能与安全。先说性能。PHP业界很有力的佐证是Facebook对PHP动态执行环境的摒弃与改造,对FB这个量级的公司是有意义的,它们不愁招不到人,也不愁招到的人驾驭不了一个自定义的编译运行时的长期迭代。一般团队是负担不起这个成本的,也没有必要,大多数Web后台只需要把数据库这一层优化好就没有什么瓶颈了。关于FB的这方面文章很多,我想不需要展开了。
安全。好像没什么证据能证明静态语言比动态语言更安全,安全最终还是取决于代码本身的质量,而静态或者动态并不决定代码质量,人决定代码质量。但是,静态语言有一个好处,能做静态分析,而动态语言要难得多,静态分析能通过一些手段提前审计代码本身的质量,所以非直接地提供了改善代码质量的途径。但大多数项目,这个好处远没有重要到可以牺牲开发效率。
比如写一组REST API,用PHP和Go,你能明显比较出来PHP或者动态开发语言的开发效率,对初、中级的开发团队尤其明显,如果用Go,碰到稍复杂的结构,不熟悉光是类型定义与转换就会费很多脑筋,而结果也并不比PHP代码质量高多少,即使Go编译出来的代码本身快很多,但无关,因为大型应用的瓶颈首先一定是数据库,离语言本身成为瓶颈还很远。
动态类型语言和静态类型语言的区别,本质上不再与规模,而在与测试。
举个例子,你要给银行开发一个5000行代码的程序,运行在他的服务器上,任务是扫【重要/机密】的log来计算某些金钱的东西(这只是随便举个例子),你敢上python?
动态语言相比静态语言没有任何优点。人们之所以觉得动态语言“方便”不过是因为大多数动态语言的实现是脚本解释器,便于编写临时的小任务和满足运维人员的需求而已(无需管理源代码和二进制文件的同步性;简单改下脚本立刻就能看到效果)因为语言和其实现是可以独立的,所以上面所说的脚本解释器的优点并不能认为是动态语言的优点 首先表明立场,动态静态没有本质上的优劣,还是那句老话,合适的才是最好的。
要说清楚这个问题,先得弄清楚动态和静态类型到底是什么。
静态类型是指变量类型初始化后就不能改变,比如a初始化为int,那它就是int了,不能给它赋值一个字符串,并不是说一定得是“int a = 1”这种有标识符的才是静态类型,比如swift这种可以通过类型推倒来决定变量类型的也可以,所以本质是类型确定了就不能变。
动态类型说的是变量的类型跟着赋值的值来定,赋值int就是int,再赋值字符串就是字符串,是的,就是这样墙头草,两边倒,你说是啥就是傻。
我看前面有朋友说 动态类型和静态类型的本质区别不是规模,而在于测试。抱歉可能是我理解不对,测试方法,不管是单元测试、集成测试、系统测试等都和语言无关,动态类型和静态类型都有各自的实现方案,而且都久经检验,所以在我看来测试这个话题本身已经和语言没有关系了,也就谈不上是语言区别的本质了,并且我也了解到银行的部分定时批量脚本(跑批)还真就是用python实现的。
那动态和静态的区别到底给编程带来了什么样不一样的感受?首先,由于静态类型类型不可变,在写程序的时候避免了很多低级的错误,最常见的是先定义了一个变量是int类型的,然后后面代码很长忘记了,又定义了一个一样的变量,换成了字符串类型,最后需要用到int类型的变量,这样的话在不知情的情况下变量的类型已经发生变化了,最后使用的时候肯定会出错,然而静态类型这种情况不允许,所以就避免了,动态类型是允许这种情况的,所以出错了语法上找不到错误,排查起来很困难,如果再是int类型和string类型自动转换的话,情况就更糟了。
总结一下就是,静态类型里的语法错误在动态类型里编程了语义错误,排查起来难度比较大,所以可能给人造成动态类型不适合大规模项目的场景。但是上面说的问题更多是开发人员自己习惯不好,变量命名不好,函数可能很长,是可以通过编程规范来约束的。BUG永远是开发人员制造的,开发人员素质不行,用什么语言都白搭,会搞出一堆feature....所谓动态语言容易出问题,更多是开发人员为自己能力不够找借口,不值得效仿!
最后说说题主关心的规模和语言适配问题,我只能说题主多虑了,思维需要看远一点。什么叫大规模项目?淘宝算大吧!那淘宝整个系统是怎么样的?分布式!不是只用一种语言,不是只有一个系统!底层中间件基本是java,底层服务层也基本是java,上层也有nodejs、php,然而这些都不是一个项目,都是分拆成很多个项目来做的,每个项目的规模都不大,而且每个项目都可以用其它语言来编写(只要符合规范),淘宝内部也正在丰富编程语言的多样性。有的人可能会说,淘宝不正是从php迁移到了java么?是的,但是并不是因为动态和静态的,是因为性能和业务需求。需要做服务化,服务发现,还有一些底层存储,php搞这些效率低下,所以才换的,不是说是因为动态语言。
还是老一句,没有具体的指标,只看是否适合自己。架构与选型是技术向业务妥协的结果!
谢谢,希望对大家有帮助。
其实静态类型和动态类型的影响不是很大。要说大项目,比如十多年前Erlang项目,AXD 301有大约200万行Erlang代码。而之前Ericsson妄图用C++开发同样的东西,没开发出来。这能不能说明动态类型比静态类型更适合大项目呢?
就是这样。 我前几天的微博。。
偶也,打完收工。。= =merge几十个changes..有按changelist的,有copy的,有临时branch里改的。。最后编译通过。。unittest通过。。然后果然就没什么问题了。这也就是静态类型语言。。这要是python。。呵呵。 准确性很重要的。使用动态语言很难保证准确。 动态语言比较适合字符串处理,或者说html文本处理而已。比如,做个网页抓取。如果用它写算法,就不行。 关于类型系统的作用,看 @雾雨魔理沙 的答案(以及同问题下很多其他答案)
http://www.zhihu.com/question/38378942/answer/84744046
--- 原答案 ---
并不是说“在一定规模和复杂度以下动态类型的语言更好”,而是说,在大多数情况下,上 Python 这种代码起步更快,如果只是希望快速解决一个问题或者跑一个简单 web 程序,用这些快速上手的东西上手做的代价更低。
应该把软件看作一个生物,每个模块是一个细胞。当这个软件代码不断“生长”后,细胞会变大,更会分裂成多个细胞,而且会演化成不同功能的细胞相互协作。细胞就是模块,而细胞的种类就是实现这个模块的语言。Web 用 Python 快速搭起来,性能关键的部分用 C / Fortran 写好,数据挖掘的部分直接上 Hadoop,都是太正常的复杂系统架构了。
p.s. PHP 这种为了单页内容设计的语言,写随便大点的项目写成一坨翔简直是应该的。