go比python的优缺点
- 部署简单。go编译生成的是一个静态可执行文件,除了glibc外没有其他外部的依赖。这让部署变得异常方便:目标机器只需要一个基础的系统和必要的管理,监控工具,完全不需要操心应用需要的各种包,库的依赖关系,大大减轻了维护的负担。这和python有着巨大的区别。由于历史原因,,python的部署工具生态相当混乱,比如setuptools,istutils,ip,buildout的不同使用场合以及兼容性问题。官方PYPI源有经常出问题,需要搭建私有镜像,而维护这个镜像又要花费不少时间和精力。
- 并发性好。Goroutine和channel使得编写高并发的服务端软件变得相当容易,很多情况下完全不需要考虑锁机制以及由此带来的各种问题。单个go应用也能有效的利用多个CPU内核,并行执行的性能好。这和python也是天壤之别。多线程和多进程的服务端程序编写起来并不简单,而且由于全局锁GIL的原因,多线程的Python的程序并不能有效利用多核,只能用多线程的方式部署;如果用标准库里的multiprocessing包又会对监控和管理造成不少的挑战(我们用的supervisor管理进程,对fork支持不好)。部署python应用的时候通常是每个CPU核部署一个应用,这会造成不少资源的浪费,比如假设某个python应用启动后需要占用100MB内存,而服务器有32个CPU核,那么留一个核给系统,运行31个应用副本就要浪费3GB的内存资源。
- 良好的语言设计。从学术的角度讲go语言其实非常平庸,不支持许多高级的语言特性;但从工程的角度讲,Go的设计是非常优秀的:规范足够简单灵活,有其他语言基础的程序员都能迅速上手。更重要的是Go自带完善的工具链,大大提高了团队协作的一致性。比如gofmt自动排版go代码,很大程度上杜绝了不同人写的代码排版风格不一致的问题。把编辑器配置成在编辑存档的时候自动运行gofmt,这样在编写代码的时候可以所以拜访位置,存档的时候自动变成正确排版的代码。此外还有gofix,govet等非常有用的工具。
- 执行性能好。虽然不如c和java,但通常比原生python应用还是搞一个数量级的,适合编写一些瓶颈业务。内存占用也非常省。
python
-
解释型语言
程序不需要在运行前编译,在运行程序的时候才编译,专门的解释器负责在每个语句执行的时候解释程序代码。这样的解释型语言每执行一次就要翻译乙烯,效率比较低。
-
动态数据类型
支持重载运算符,也支持泛型设计。(运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以使用不同的数据类型。泛型设计就是定义的时候不需要指定类型,在客户端使用的时候再去指定类型)
-
完全面向对象的语言
函数,模块,数字,字符串都是对象,在python,一切皆对象
完全支持继承,重载,多重继承
-
拥有强大的标准库
python 语言的核心只包含数字,字符串,列表,元组,字典,集合,文件等产检类型和函数,而由python标准库提供了系统管理,网络通信,文本处理,数据库接口,图形系统,xml处理等额外的功能。
-
社区提供了大量的第三方库
python社区提供了大量的第三方模块,使用方式与标准库类似。他们的功能覆盖科学计算,人工智能,机器学习,web开发,数据库接口,图形系统多个领域
golong
-
静态强类型,编译型,并发型
静态类型语言,但是有动态语言的感觉。(静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉是有很多的包可以使用,写起来的效率很高)
可直接变异成机器码,不依赖其他库,glibc版本有一定要求,部署就是扔一个文件上去就完成了。
语言层面支持并发,这个就是go最大的特色,天生的支持并发。GO就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发。
-
垃圾回收机制
内置runtime,支持垃圾回收,这属于动态语言的特性之一吧,虽然目前来说Gc(内存垃圾回收机制)不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的Gc
-
支持面向对象编程
有接口类型和实现类型的概念,但是用嵌入代替了继承。
-
丰富的标准库
go目前已经内置了大量库,特别是网络库非常强大
-
内嵌c支持
go里面也可以直接包含c代码,利用现有的丰富的C库
应用:
python
-
网络编程
web应用,网络爬虫
-
数据分析和机器学习
-
自动化测试
-
自动化运维
golong
-
服务器编程
处理日志,数据打包,虚拟机处理,文件系统等
-
分布式系统,数据库代理期等
-
网络编程
这一块目前应用最广,包括web应用,API应用,下载应用
-
内存数据库
如google开发的groupcaphe,couchbase的部分组件
-
云平台
go语言的缺点
-
缺少框架(go语言没有一个主要的框架)
-
错误处理
- go语言通过函数和语气的调用代码简单的返回错误(或返回调用堆栈)而帮助开发者处理编译报错。虽然这种方法是有效的,单数很容易丢失错误发生的范围,因此我们也很难想用户提供有意义的错误信息。错误包(errors package)可以允许我们添加返回错误的上下文和堆栈追踪而解决该问题
- 另一个问题是我们可能会忘记处理报错。诸如errcheck和megacheck等静态分析工具可以避免出现这些失误。虽然这些解决方案十分有效,但可能并不是那么正确的方法。
-
软件包管理
go语言的软件包管理绝对是不完美的。默认情况下,他没有办法制定特定版本的依赖库,也无法创建可复写的builds。相比之下python,node和ruby都有更好的软件包管理系统。然而通过正确的工具,go语言的软件包管理也可以表现得不错。
我们可以使用dep来管理依赖项,他也能指定的软件包版本。除此之外,我们还可以使用一个名为virtualgo的开源工具,他能轻松的管理go语言编写的多个项目。
(ps:本篇博客由作者通过资料总结,如有侵权请联系删除)