我的编程空间,编程开发者的网络收藏夹
学习永远不晚

选择Go好还是Java好

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

选择Go好还是Java好

这篇文章主要介绍“选择Go好还是Java好”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“选择Go好还是Java好”文章能帮助大家解决问题。

1. 初遇 Go

2017 年初,我接手了一个非常有趣的项目,一个用于监控和种植水培植物的自动化编程系统。项目的原始代码里包含了一个使用 CGo 开发的支持三个不同系统(Windows、MacOS 和 ARM)的网关。

因为对 Go 不熟悉,我一边学习,一边用它来实现功能。因为已有代码库的结构非常复杂,对我来说是难上加难。用 Go 开发的支持三种不同操作系统的程序意味着需要针对三种不同的系统进行部署、测试和运行维护。此外,代码采用了单例设计模式,导致系统严重相互依赖,难以预测会出现什么问题,而且难以理解。最后,我选择使用 Java 来实现新版本,但最终也变得非常丑陋和令人困惑。

在加入 Spiral Scout 后,我尝试停止使用 Java。我决定拥抱 Go,并尽可能多地使用 Go 来开发。我发现它是一种创新且全面的语言,我们的团队现在仍然每天在各种项目中使用它。

但是,与任何一门编程语言一样,Go 也有它的缺点,而且我不想撒谎——有时候我真的很想念 Java。

如果说我的编程经验教会了我什么,那一定是——软件开发没有银弹。我将在这篇文章里详细分享我使用一门传统语言和一门新语言的经历。

2. 简洁性

Go 和 Java 都是 C 家族语言,所以它们具有相似的语法。因此,Java 开发人员可以很容易读懂 Go 代码,反之亦然。Go 不需要在语句末尾使用分号(';'),只有少数情况例外。对我来说,Go 的行分隔方式更清晰,更易读。

Go 和 Java 都使用了我最喜欢的功能之一,即垃圾收集器(GC),用来帮助防止内存泄漏。与 C++ 不同,C 家族的程序员需要处理内存泄漏问题。垃圾回收器是自动化内存管理的一个特性,减轻了程序员的负担。

Go 的 GC 并未使用“弱世代假设”,但它的表现仍然非常出色,并且 STW(Stop-the-World)的时间非常短。在 1.5 版中,STW 降得更多,并且很稳定,而在 1.8 版中,它降到了 1 毫秒以下。

Go 的 GC 只有少量的一些选项,即用于设置初始垃圾回收目标百分比的 GOGC 变量。而 Java 有 4 个不同的垃圾回收器,每个垃圾回收器都有大量的选项。

尽管 Java 和 Go 都被认为是跨平台的,但 Java 需要 Java 虚拟机(JVM)来解释编译后的代码,而 Go 是将代码编译成目标平台的二进制文件。但我认为,与 Go 相比,Java 对平台的依赖程度更低,因为 Go 每次都需要为新平台编译二进制文件。从测试和 DevOps 的角度来看,分别为不同的平台编译二进制文件非常耗时,并且跨平台的 Go 编译在某些情况下不起作用,尤其是在使用 CGo 时。而对于 Java,你可以在安装了 JVM 的任何地方使用相同的 jar。Go 需要的 RAM 更小一些,并且不需要安装和管理虚拟机。

反射。Java 的反射更方便、更流行也更常用,而 Go 的反射似乎更复杂。Java 是一种面向对象的编程语言,因此除原始类型之外的所有东西都被视为对象。如果要使用反射,可以创建一个类,并从类中获取所需的信息,如下所示:

Class cls = obj.getClass();Constructor constructor = cls.getConstructor();Method[] methods = cls.getDeclaredFields();

这样就可以访问构造函数、方法和属性,然后调用或对它们赋值。

Go 没有类的概念,并且结构体只包含了已声明的字段。因此,我们需要借助“reflection”包来获得所需的信息:

type Foo struct {  A int `tag1:"First Tag"  tag2:"Second Tag"`  B string}f := Foo{A: 10, B: "Salutations"}fType := reflect.TypeOf(f)switch t.Kind(fType)    case reflect.Struct:        for i := 0; i < t.NumField(); i++ {          f := t.Field(i)          // ...        }}

我觉得这不是一个大问题,但由于 Go 中没有结构体的构造函数,所以很多原始类型必须单独处理,并且需要考虑到指针。在 Go 中,我们可以进行指针传递或值传递。Go 的结构体可以将函数作为字段。所有这些都让 Go 的反射变得更加复杂。

可访问性。Java 有 private、protected 和 public 修饰符,为数据、方法和对象提供了不同的访问作用域。Go 有与 Java 的 public 和 private 相似的 exported/unexported,但没有修饰符。以大写字母开头的所有内容都将被导出,对其他包可见,未导出(小写)的变量或函数仅在当前包中可见。

3. Go 与 Java 的大不同

Go 不是面向对象编程语言。Go 没有类似 Java 的继承机制,因为它没有通过继承实现传统的多态性。实际上,它没有对象,只有结构体。它可以通过接口和让结构体实现接口来模拟一些面向对象特性。此外,你可以在结构体中嵌入结构体,但内部结构体无法访问外部结构体的数据和方法。Go 使用组合而不是继承将一些行为和数据组合在一起。

Go 是一种命令式语言,Java 是一种声明式语言。Go 没有依赖注入,我们需要显式地将所有东西包装在一起。因此,在使用 Go 时尽量少用“魔法”之类的东西。一切代码对于代码评审人员来说都应该是显而易见的。Go 程序员应该了解 Go 代码如何使用内存、文件系统和其他资源。

Java 要求开发人员更多地地关注程序的业务逻辑,知道如何创建、过滤、修改和存储数据。系统底层和数据库方面的东西都是通过配置和注解来完成的(比如通过 Spring Boot 等通用框架)。我们尽可能把枯燥乏味的东西留给框架去做。这样做很方便,但控制也反转了,限制了我们优化整个过程的能力。

变量定义的顺序。在 Java 中,你可以这样定义变量:

String name;

而在 Go 中,你得这么写:

name string

在我刚开始使用 Go 时,这也是令我感到困惑的一个地方。

4. Go 好的方面

简单优雅的并发。Go 具有强大的并发模型,叫作“通信顺序进程”或 CSP。Go 使用 n-to-m 分析器,允许在 n 个系统线程中执行 m 个并发。启动并发例程非常简单,只需使用 Go 的一个关键字即可,例如:

go doMyWork()

这样就可以并发执行 doMyWork()。

进程之间的通信可以通过共享内存(不推荐)和通道来完成。我们可以使用与环境变量 GOMAXPROCS 定义的进程数一样多的核心,并带来非常健壮和流畅的并行性。默认情况下,进程数等于核心数。

Go 提供了一种特殊模式来运行二进制文件,并可以检测执行竟态条件。我们可以通过这种方式测试并证明自己的程序是不是并发安全的。

go run -race myapp.go

应用程序将在竟态检测模式下运行。

Go 提供了很多开箱即用且非常有用的基本功能(https://golang.org/dl/),例如用于并发的“sync”包。“Once”类型的单例可以这么写:

package singleton import ("sync")type singleton struct { }var instance *singleton var once sync.Once func GetInstance() *singleton {      once.Do(func() {            instance = &singleton{}      })      return instance }

sync 包还为并发 map 实现、互斥锁、条件变量和 WaitGroup 提供了一种结构体。atomic 包(https://golang.org/pkg/sync/atomic/) 支持并发安全转换和数学运算——它们基本上是编写并发代码所需的一切。

指针。借助指针,Go 可以更好地控制如何分配内存、垃圾回收器负载以及其他在 Java 中无法实现的性能调优。与 Java 相比,Go 更像是一种低级的语言,并且支持更容易、更快的性能优化。

鸭子类型(Duck Typing)。“如果它走路像鸭子,并且像鸭子一样嘎嘎叫,那它一定就是鸭子”。在 Go 中就是这样的:无需定义某种结构体是否实现了给定的接口,只要这个结构体具有与给定接口相同的方法签名,那它就是实现了这个接口。这非常有用,作为代码库的调用端,你可以定义外部库结构体所需的任意接口。而在 Java 中,对象必须显式声明实现了哪些接口。

性能分析器。Go 的性能分析工具让性能问题分析变得便捷和轻松。Go 的分析器可以揭示程序的内存分配和 CPU 使用情况,并在可视化图形中展示出来,让性能优化变得非常容易。Java 也有很性能分析器,比如 Java VisualVM,但它们都比 Go 的复杂,而且依赖 JVM 的运行情况,因此它们提供的统计信息与垃圾回收器的运行相关。

CGO。Go 可以与 C 语言集成,因此你可以在 Go 项目中开发带有 C 代码片段的应用程序。开发人员可以使用 CGo 创建调用 C 代码的 Go 程序包。Go 为 exclude/include 给定平台的 C 代码片段提供了各种构建选项。

将函数作为参数。Go 函数可以作为变量传递给另一个函数或作为结构体的字段。这种多功能性令人耳目一新。Java 8 引入了 lambda,但它们不是真正的函数,只是单函数对象。

清晰的代码风格准则。Go 社区提供了很多示例和说明:

https://golang.org/doc/effective_go.html

函数可以返回多个参数,这个也非常有用。

package main import "fmt" func returnMany() (int, string, error) {       return 1, "example", nil }func main() {       i, s, err := returnMany()       fmt.Printf("Returned %s %s %v", i, s, err) }

5. Go 不好的方面

没有多态性(除非通过接口来实现)。在 Go 中,如果在同一个包中有两个函数具有不同的参数但含义相同,必须给它们指定不同的名字。例如这段代码:

func makeWorkInt(number int) {     fmt.Printf(“Work done number %d”, number) }func makeWorkStr(title string) {     fmt.Printf(“Work done title %s”, title) }

这样一来,你就会得到很多方法,它们做的事情差不多,但名字都不一样,而且看起来很“丑”。

另外,Go 也没有继承多态性。被嵌入到结构体里的结构体只知道其自己的方法,对“宿主”结构体的方法一无所知。对于像我这样的开发人员来说,这尤其具有挑战性,因为我们是从其他 OOP 语言(最基本的概念之一就是继承)过渡到 Go 的。

不过,随着时间的推移,我开始意识到这种处理多态性的方法只是另一种思维方式,而且是有道理的,因为组合比继承更加可靠,并且运行时间是可变的。

错误处理。在 Go 中,完全由你来决定返回什么错误以及如何返回错误,因此作为开发人员,你需要负责返回和传递错误。毫无疑问的是,错误可能会被隐藏掉,这是一个痛点。时刻要记得检查错误并把它们传递出去,这有点烦人,而且不安全。

当然,你可以使用 linter 来检查隐藏的错误,但这只是一种辅助手段,不是真正的解决方案。在 Java 中,处理异常要方便得多。如果是 RuntimeException,甚至不必将其添加到函数的签名中。

public void causeNullPointerException() {  throw new NullPointerException("demo");}try {  causeNullPointerException();} catch(NullPointerException e) {  System.out.println("Caught inside fun().");  throw e; // rethrowing the exception}

没有泛型。虽然泛型很方便,但它会增加复杂性,而且从类型系统和运行时方面来看,泛型的成本很高。在构建 Go 代码时,你需要处理各种不同的类型或使用代码生成。

没有注解。尽管可以用代码生成替换一部分编译时注解,但运行时注解是不能替换的。这是有道理的,因为 Go 不是声明式的,并且代码里不应该包含任何“魔法”。我喜欢在 Java 中使用注解,因为它们让代码更优雅、简单和简约。

在为 HTTP 服务器端点生成 swagger 文件时,注解会非常有用。目前在 Go 中需要手动编写 swagger 文件,或者为端点提供特别的注释。每次 API 发生改动时,这都是一件很痛苦的事情。但是,Java 中的注解就像是一种魔法一样,人们通常都不用去关心它们是怎么实现的。

Go 的依赖管理。我之前曾写过一篇关于如何使用 vgo 和 dep 在 Go 中进行依赖管理的文章。Go 的依赖管理的演变之路充满了坎坷。最初,除了“ Gopgk”之外没有其他依赖管理工具,后来发布了实验性的“Vendor”,后被“vgo”取代,然后又被 1.10 版“go mod”取代。如今,我们可以手动或者使用各种 Go 命令(例如“go get”)来修改 go.mod 文件描述符,但这也让依赖关系变得不稳定。

Java 有 Maven 和 Gradle 之类的声明式工具,用来进行依赖关系管理,也用于构建、部署和处理其他 CD/CI 任务。但是,在 Go 中,我们必须使用 Makefile、docker-composes 和 bash 脚本自定义构建所需的依赖管理,这只会使 CD/CI 的过程和稳定性变得更加复杂。

包的名称里包括了托管域名。例如:

import "github.com/pkg/errors"

这真的很奇怪,而且很不方便,因为你不能在不修改项目代码库导入的情况下用自己的实现替换别人的实现。

在 Java 中,导入通常以公司名称开头,例如:

import by.spirascout.public.examples.simple.Helper;

区别在于,在 Go 中,go get 会向 by.spirascout.public 获取资源。在 Java 中,包名和域名不一定是相关联的。

关于“选择Go好还是Java好”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

选择Go好还是Java好

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

选择Go好还是Java好

这篇文章主要介绍“选择Go好还是Java好”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“选择Go好还是Java好”文章能帮助大家解决问题。1. 初遇 Go2017 年初,我接手了一个非常有趣的项目,
2023-06-27

网站空间选择Windows系统好还是Linux系统好

本篇内容介绍了“网站空间选择Windows系统好还是Linux系统好”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!国内虚拟主机主要是指虚拟主
2023-06-07

Win10系统选8G好还是16G好

本篇内容介绍了“Win10系统选8G好还是16G好”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一台相对正常的Win10电脑,无论是优化的再
2023-06-28

网站建设选择服务器好还是虚拟主机好

这取决于您的网站规模和需求。如果您的网站流量较大或需要更高的安全性和性能,那么选择服务器可能更合适。服务器提供了更多的资源和控制权,可以满足更高级的需求。虚拟主机通常适用于小型网站或个人网站,资源较少但价格更便宜。因此,根据您的具体情况和需
网站建设选择服务器好还是虚拟主机好
2024-04-28

租用服务器选择高防IP好还是高防CDN好

租用服务器时选择高防IP还是高防CDN取决于您的需求和预算。如果您主要关注网络安全和防御DDoS攻击,那么选择高防IP是一个不错的选择。高防IP可以帮助您保护服务器免受网络攻击,确保网站和应用程序运行的稳定性和安全性。另一方面,如果您需
租用服务器选择高防IP好还是高防CDN好
2024-05-08

论坛搭建选择虚拟主机好还是云服务器好

虚拟主机和云服务器是论坛搭建的常见选择。本文比较了它们的成本、性能、控制、安全性、可用性、技术支持和可定制性,以帮助您做出明智的决定。对于小型论坛或预算有限的情况,虚拟主机是经济实惠的选择。对于大型论坛或重视性能、可扩展性和控制的用户,云服务器是更佳选择。考虑您的论坛需求和技术技能,以权衡这些托管解决方案的利弊。
论坛搭建选择虚拟主机好还是云服务器好
2024-04-09

论坛搭建选择虚拟主机好还是云服务器好

虚拟主机和云服务器都有各自的优点和适用场景,选择哪种方式搭建论坛取决于你的需求和预算。虚拟主机是由服务提供商管理的物理服务器上的虚拟环境,适合小型论坛或访问量较低的网站。它的优点包括价格相对低廉、易于管理和维护,无需担心硬件故障和安全问题。
2023-08-26

选云主机好还是虚拟主机好

选择云主机还是虚拟主机取决于您的需求和预算。云主机是基于云计算技术的虚拟化服务器,可以提供弹性的资源分配和高可用性。云主机适合需要灵活扩展计算资源、具有高可用性和容灾能力的业务。它可以根据需求快速调整配置,并提供可靠的数据备份和恢复机制。虚
2023-09-20

服务器好还是阿里云好对比分析与选择建议

简介:在云计算时代,服务器和云服务成为企业和个人构建IT基础设施的重要方式。本文将对服务器和阿里云进行对比分析,以帮助读者更好地了解它们的优缺点,并提供选择建议。详细说明:一、服务器与阿里云的差异硬件设施:服务器通常由用户自己购买和维护,需要具备一定的技术能力来安装和配置硬件设备。而阿里云作为云计算服务提供商,拥有大规
服务器好还是阿里云好对比分析与选择建议
2024-01-22

做网站选择香港服务器好还是国内服务器好

选择香港服务器或国内服务器取决于您的具体需求和情况。以下是一些考虑因素:网站受众:如果您的目标受众主要在中国大陆,那么选择国内服务器可能会让访问速度更快,因为国内服务器与中国大陆网络连接更稳定。数据安全:香港服务器通常受到更严格的监管和法律
做网站选择香港服务器好还是国内服务器好
2024-04-09

mysql好还是sqlserver好

对于小型到中型应用程序,mysql 易用、开源且经济实惠;对于大型或复杂的应用程序,sql server 提供更广泛的功能、更高的性能和更好的企业支持。考虑因素包括:应用程序大小、预算、支持要求、扩展性和特定行业需求。MySQL 与 SQL
mysql好还是sqlserver好
2024-08-01

云服务器租用选linux好还是windows好

选择云服务器的操作系统应根据您的需求和技术能力来决定。以下是一些考虑因素:1. 技术能力:如果您熟悉Linux的命令行界面和管理工具,那么选择Linux可能更适合您。相比之下,Windows具有更友好的图形用户界面和易于使用的管理工具。2.
2023-08-08

个人网站搭建选择虚拟主机好还是云服务器好

个人网站搭建选择虚拟主机还是云服务器,主要取决于以下几个因素:1. 网站流量和访问量:如果你的网站预计会有大量的访问量和高流量,云服务器可能更适合,因为它可以提供更好的性能和扩展性。2. 成本:虚拟主机通常比较便宜,适合个人网站或小型业务,
2023-08-26

个人网站搭建选择虚拟主机好还是云服务器好

个人网站搭建:虚拟主机与云服务器的选择对于个人网站,虚拟主机更便宜、易用,无需维护。但资源有限、自定义性差、安全性低。云服务器可扩展、可定制、性能高,但成本较高、需要技术技能、维护责任大。选择时考虑:网站流量:低流量适合虚拟主机,高流量适合云服务器可扩展性需求:预期增长适合云服务器自定义需求:高度自定义适合云服务器预算:虚拟主机较便宜技术技能:缺乏技能适合虚拟主机
个人网站搭建选择虚拟主机好还是云服务器好
2024-04-12

阿里云服务器国内还是国外选择好

阿里云服务器国内还是国外选择好,取决于您的具体需求和预算。如果您的目标是高可用性和稳定性,那么国内云服务器可能是您的更好选择,因为这些服务提供商通常会为其服务器配置高性能的数据中心和安全措施。而且,许多大型公司都在使用云服务器,因为它们需要一个稳定的基础设施来处理日常应用程序和数据库查询,因此它们更倾向于选择国内云服务器。如果您的目标是性能和弹性,那么国外云服务器可能更适合您。例如,您可能需要高性能计算和...
2023-10-27

建站选虚拟主机好还是云主机好

虚拟主机和云主机都有各自的优势和适用场景,具体选择取决于您的需求和预算。虚拟主机适合小型网站或个人博客,价格相对便宜,资源较有限,适合对服务器管理不熟悉的用户。虚拟主机通常提供简单的控制面板,方便管理网站。云主机适合需要更高性能和可扩展
建站选虚拟主机好还是云主机好
2024-05-07

DDoS攻击选高防服务器好还是选高防CDN好

对于DDoS攻击,选择高防服务器和高防CDN都有各自的优势和适用场景。选择高防服务器的好处是可以直接保护服务器本身,防止攻击直接打到服务器上,保障服务器的稳定运行。高防服务器通常具有强大的防御能力和专业的DDoS防护设备,能够有效抵御各种
DDoS攻击选高防服务器好还是选高防CDN好
2024-05-15

Java与Python该选择哪个好

本篇内容主要讲解“Java与Python该选择哪个好”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java与Python该选择哪个好”吧!是什么?Java 是一门通用面向对象的编程语言,主要用于
2023-06-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录