这里仅从一个业务开发的角度谈谈体会,格局较低,仅做个人记录
编程语言是程序员接触和使用最多的工具
后端技术基础的深度是快速学习和适应新语言的关键
基于对工作中接触过的几种编程语言及其部署架构的看法继续聊。
截至目前,职业生涯五分之四的时间都是在使用Java。出于个人意愿和兴趣,以及行业的发展形势,也系统的自学了Go语言,并在个人的小项目实践。在一次意外的组织变动中,我转岗到了新团队,并开始使用Go,由于之前自己的自学基础,基本是无缝切换到新语言。可能是由于团队人员大部分是从Lua或PHP开始转Go的,在那里甚至感觉自己稍稍领先。
Go抽象业务比Java麻烦,代码不美观,但是它原生高并发,而且微服务下很多时候就一个后端服务,业务足够小,不需要复杂的设计模式等,并不需要像以前写大型Java应用这样做非常多的抽象,还能打二进制包,甚至还能保证一个团队所有人代码都是相同风格
以下讲一些个人看法,比较乱甚至不正确,仅做个人记录
- 小型项目省内存
- 写命令行程序方便简单
- 现在绝大部分功能都有相应的官方库和开源库
- 运行无需环境依赖,直接打包成二进制可执行程序(Java现在也可以了,可能大部分业务场景下体积还较大)
- 支持交叉编译,不要特定平台
- 打包体积小(根据代码实际使用情况打包-这点是我一直苦苦寻找的)
- Go语言中有未用代码消除和可执行文件瘦身机制。只有在程序执行路径上被调用的函数才会进入最终的可执行文件,未被调用的函数会被消除
- Go未用代码消除与可执行文件瘦身
为什么现在大多数人都会认为Java启动慢占内存呢?
- 首先不是Java自身的原因,而是跟实际使用场景有关
- 使用Java大多数用来做业务开发,也习惯引入很多依赖库,首当其冲就是SpringBoot等框架
- 多数都是spring相关类、proxy/cglib,以及各种bean配置
- 而且很多类都是在启动的时候初始化的
微服务下的编程语言
- 在K8S流行之前,Java通常是使用SpringCloud
- 其实微服务相关技术,在K8S已经实现了
- 无论是使用Go还是Java,目前都应该向K8S靠近
- 还有一点,K8S本身就是用Go实现的
扩展
在内存利用效率上,Go语言确实比Java做得更好,在4个不同的角度来总结
- Java的JIT策略比Golang的AOT策略
- Java在运行时相比Golang多占用了一些内存。原因在于:
- Java运行态中包含了一个完整的解释器、一个JIT编译期以及一个垃圾回收器,这会显著地增加内存。
- Golang语言直接编译到机器码,运行态只包含机器码和一个垃圾回收器。
- 因此Golang的运行态相对消耗内存较少。
- Java在运行时相比Golang多占用了一些内存。原因在于:
- 内存分配和垃圾回收器
- Java确实在起步占用上偏多,毕竟jvm需要更多内存做jit,默认的gc算法对内存要求偏高,但这不能代表后续占用仍然线性增长。如果目标是启动成百上千个内存需求较少的进程,那Java确实不擅长。
- 并发
- 协程模型比线程模型更加节省内存。
- 反射
- Golang的反射更加简单,导致框架的内存消耗Golang程序比Java程序优秀。主要是因为: Java的框架实现中大量使用反射,并使用hashmap缓存信息,这2个都是极度消耗内存的行为。 Golang的框架中也使用reflect、map。但是Golang是面向interface和值类型的,这导致Golang的反射模型要比Java的反射模型简单非常多,反射过程要产生的对象数量也少非常多。
- Java的JIT策略比Golang的AOT策略
为什么一些已经选择 Java 的公司,现在又开始考虑使用 Go?
- 为什么要用Go重写Dubbo?
- 相较于 Java,Go 在启动速度、编译速度、内存使用和高并发(如协程)方面都有明显优势。所以,那些已经采用 Java 的公司现在也在考虑引入 Go。但要注意的是,目前这样的公司仍然是少数。另外,一些公司并没有严格规定技术栈的选择,因此新成立的部门或新业务团队可以自由选择,而他们可能更倾向于选择 Go 作为开发语言。
- 小结: 总的来说,无论是选择 Java 还是 Go,都是有其合理性的。一家公司同时选择这两种语言也同样合理。尽管这样的公司占比不大,但 Java 与 Go 之间的交流需求仍然存在。