惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
Lohrmann on Cybersecurity
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog
TaoSecurity Blog
TaoSecurity Blog
博客园_首页
Vercel News
Vercel News
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
量子位
Project Zero
Project Zero
A
Arctic Wolf
小众软件
小众软件
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
Schneier on Security
Schneier on Security
The Hacker News
The Hacker News
K
Kaspersky official blog
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Webroot Blog
Webroot Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
人人都是产品经理
人人都是产品经理
AI
AI
Cisco Talos Blog
Cisco Talos Blog
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
S
Schneier on Security
P
Palo Alto Networks Blog

文章列表 on polarisxu

通过一个例子让你彻底掌握 Go 工作区模式 这道题正确率竟然只有 22% Go 开源项目推荐:一个简单的 Go 练手项目 go test 如何禁用缓存? Go1.18 快讯:constraints 包被移除标准库 跟着 Go 作者学泛型 「2022 版」轻松搞定 Go 开发环境 鹅厂小哥用行动反对加班:程序员加班能被终结吗? Go 为什么选择 Gopher 作为吉祥物? 本地如何配置多个 GitHub/Gitee 账号? 为 Java 开发者准备的 Go 教程 02:Java 有而 Go 无 GitHub 发现了 studygolang 项目依赖的漏洞 Typora 宣布收费后,这款开源 Markdown 编辑器火了 我的 2021 年终总结 泛型版 singleflight:Go 中如何防止缓存击穿? 2021 年你写了多少代码?这个 Go 工具帮你统计 Go1.18 新特性:TryLock Go 泛型入门教程 程序员瑞士军刀:各种结构的转换工具 终于有 Go 版的 Elasticsearch 了 Go泛型系列:maps 包讲解 Go 1.18 中的 any 是什么? Go1.18 快讯:新的 IP 包 Go编程模式:详解函数式选项模式 Go泛型系列:slices 包讲解 Nginx 竟然也有 playground — Go 语言构建的 Go泛型系列:Go1.18 类型约束那些事 Go1.18 快讯:Module 工作区模式 Go1.18 快讯:新增的 Cut 函数太方便了 Go1.18 快讯:废弃了这个 API Go1.18 快讯:新增字符串 Clone API Go:如何获得项目根目录? Go 如何获取和设置环境变量 重磅变动:更快找到微信公众号里的Go文章 Go 这样设置版本号:我们的项目也可以 假期结束,推荐 2 本 manning 出的 Go 图书 Go Fiber 框架系列教程 04:测试应用 Go Fiber 框架系列教程 03:中间件 Go泛型系列:提前掌握Go泛型的基本使用 推荐一个 Go GUI 实战项目 Go Fiber 框架系列教程 02:详解相关 API 的使用 Go Fiber 框架系列教程 01: 和 Express 对比学习 Go Module:私有不合规库怎么解决引用问题 Go1.17 新特性:go get 变了 Go1.17 新特性:testing 包的相关变化 StackOverflow 上关于 Go select 死锁的问题 新书推荐:用 Gin 框架构建分布式应用 Go 官网要变天。。。 Gin 这是要成为 Go 官方框架? 扬眉吐气:刚刚,Go 已经默认支持泛型了 Go 1.17 新特性:Module 有哪些变化? Go 第三方库推荐:类型转换如此简单 担心密码提交到 GitHub?建议使用这个 Go 开源工具 Go 的时间格式化为什么是 2006-01-02 15:04:05? GitHub 为 Go 社区带来安全支持 Go开源项目推荐:500行代码确认请求时间花在哪 一道关于 len 函数的诡异 Go 面试题解析 厉害了我的 Go:推荐系统都有开源实现 Go1.17 新特性:新版构建约束 这个工具真好:看看你的Go项目依赖有无漏洞 网友很强大,发现了Go并发下载的Bug Rust 劝退系列 09:函数 Go项目实战:一步步构建一个并发文件下载器 这本 Go 新书挺期待的:100 个常见错误 Go 启用新的官方问答社区 这是要干嘛?!微软招 Go 编译器全职开发人员 Go1.17 快报之标准库越来越注重易用性 Go1.17 新特性之切片变数组 回顾 Go 官网的演变史 站长8年前的Go代码竟然进入大厂的项目里了 Go图书翻译:一个好消息,一个坏消息 不怕烂尾!决定组织翻译这本 Go 图书 Rust 劝退系列 08:模式匹配 一本花了2.5年写成的Go免费在线图书 被黑惨了:一句话,说明自己会 Go,咋整? Go1.16 中的新函数 signal.NotifyContext 怎么用? Go 1.17 新特性提前学之测试执行随机化 Rust 劝退系列 07:流程控制 官方的 Go 多版本管理:使用和原理 Rust新书:给你一个劝退的理由 周刊题解:常量表达式这个规则应该了解下 盘点那些使用 Go 语言的国外公司 编写了50万行Go代码是一种什么体验 Rust 劝退系列 06:常量 Uber 使用 Go 的规模这么大?!都自己定制的 Go 编译器了 Go Team Leader — rsc 大神新开源了一个库,增强模板功能 再一次看到了 Go 的节制:int128 类型要不要支持? Rust 劝退系列 05:复合数据类型 「卷」有理论依据:海勒姆定律—Go又是怎么卷的 Go 真的也可以进行 GUI 开发:还有这样的图书呢 Rust 劝退系列 04:基本数据类型 我的 Go 语言书单 Rust 劝退系列 03:变量 我又来推荐免费 Go 新书了:一本用 Go 讲架构的书 注释竟然还有特殊用途?一文解惑 //go:linkname 指令 这个功能,公众号、微信群会不会被玩坏? 一道 Go 闭包题,面试官说原来自己答错了:面别人也涨知识 Rust 劝退系列 02:第一个 Rust 程序 Rust 劝退系列 01:打造开发环境 答应我,这次一定彻底搞懂 Go 中的类型别名
为 Java 开发者准备的 Go 教程 01:漫游了
2022-01-05 · via 文章列表 on polarisxu

大家好,我是 polarisxu。

在正式工作之前,一直使用 Java,虽然这些年对 Java 的关注变少了,但很显然,Java 用户群体特别大。不过,我也知晓,有不少 Java 用户在学 Go。我尝试写一系列文章,为 Java 开发者讲解 Go 语言。

这是第一篇,从大的层面简单对比下 Go 和 Java,算作是一次漫游。


整体上,Java 和 Go 之间有许多明显而微妙的区别,包括语言层面和运行时层面。我们这里主要在语言层面漫游。

这里的比较,没有贬低哪门语言的意思,旨在客观指出各自的特点。

Go 和 Java 都是 C 系语言,但 Go 更接近 C,包括风格、库等。

与 C/C++ 一样,Go 语言源码会直接编译成目标计算机体系结构的机器语言。而 Java 源码编译成虚拟机语言,即字节码,并由 Java 虚拟机(JVM)进行解释(interpreted)。为了提高性能,字节码通常在运行时被动态编译成机器语言。JVM 本身是为特定的操作系统和硬件体系结构构建的。

而且 Go 是静态编译,一旦编译完成,Go 程序只需要一个操作系统就可以运行。Java 程序在运行之前需要计算机上安装有 JRE(特定版本)。许多 Java 程序可能还需要额外的第三方代码。

所以,虽然 Go 和 Java 都是跨平台的,但实现形式还是很不一样。

02 Go 和 Java 程序结构类似

这两门语言都支持包含方法和字段的数据结构的概念。在 Go 中,它们被称为 struct(结构体),而在Java中,它们被称为 class(类)。这些结构被收集到称为包(package)的分组中。在这两门语言中,包都可以分层排列(即嵌套包)。

Java 包顶层只包含类型声明。Go 包可以各种声明,如变量、常量、函数以及派生类型声明。

两门语言都通过导入(import)来访问不同包中的代码。在 Java 中,可以选择使用导入的类型(String 或 Java.lang.String)。在 Go 中,所有导入的名称必须始终是限定的(虽然可以本地导入,但不建议使用)。

03 Go 和 Java 代码风格的差异

这方面涉及到的内容不少,无法一一列出。这里提一些:

1)Go 与众不同,变量声明,类型放在后面。语言通常省略分号。

Java:int x, y, z;

Go:var x, y, z int

2)Java 方法只能返回一个值。Go 函数/方法可以返回许多值。

3)Java 方法和字段必须在它们所属的类型内声明。Go 方法是在所属类型之外定义的。Go 支持独立于任何类型的函数和变量。Java 没有真正的静态共享变量;静态字段只是某些类(相对于实例)的字段。Go 支持在可执行映像中分配的真正静态(全局)变量。

4)Java 只允许其他类型(类、枚举和接口)的类型扩展,而 Go 可以基于任何现有类型创建新类型,包括基本类型(如整数和浮点)和其他用户定义的类型。Go 可以支持这些自定义类型中的任何一种。

5)Go 和 Java 接口的工作方式非常不同。在 Java 中,类(或枚举)实现接口时,必须显式指定。在 Go 中,任何类型都可以通过实现接口的方法来实现接口,即隐式实现接口,所谓的鸭子类型。

6)Java 通过 try/catch 处理异常。Go 中是 error,另外有 panic 和 recover。

04 Java 是面向对象语言,而 Go 不完全是

面向对象的三大特性:封装、继承和多态。

Go 没有继承的概念,认为组合优于继承。不过,在 Go 中,可以通过内嵌来模仿部分类似继承的功能,但本质还是组合。

此外,Go 只在接口层面有多态,没有方法重载。

05 Java 不少特性是基于 Annotation 的,Go 没有 Annotation

许多 Java 库(特别是框架,比如Spring),都充分利用了 Java 的注解(Annotation)。注解提供元数据(通常在运行时使用),以修改库提供的行为。Go 没有注解,因此缺少此功能。Go 可以使用代码生成(go generate)获得与注释类似的结果。Go 有一种简单的注解形式,称为 tag,可用于自定义某些库行为,如 JSON 或 XML 格式。

06 Go 和 Java 都使用 GC 管理内存

这两门语言都使用 stack 和 heap 来保存数据。栈主要用于函数局部变量,堆用于其他动态创建的数据。在 Java 中,所有对象都在堆上分配。在 Go 中,堆上只分配可在函数生命周期之外使用的数据(通过逃逸分析确认)。在 Java 和 Go 中,堆都是垃圾收集的;堆对象由代码显式分配,但总是由垃圾收集器回收。

Java 没有指向对象的指针的概念,只引用位于堆中的对象。Go 允许访问指向任何数据值的指针(或地址)。在大多数情况下,Go 的指针可以像 Java 引用一样使用。

Go 的垃圾收集实现比 Java 的更简单,通常 Go GC 需要调优的情况较少(没有太多选项可配置)。

07 Go 和 Java 都支持并发,但方式不同

Java 有线程(Thread)的概念。而 Go 是 Goroutine,它是由语言提供的。Goroutine 通常被称为轻量级线程。Go 运行时支持使用比 JRE 支持的线程多得多的 Goroutine。

Java 支持同步控制。Go 具有类似的库函数。Go 和 Java 都支持跨 Thread/Goroutine 安全更新的原子值的概念。两者都支持显式锁定库。

Go 提供了通信顺序进程(CSP)的概念,作为 Goroutine 在没有显式同步和锁定的情况下进行交互的主要方式。Goroutine 通过 channel 进行通信,channel 是有效的管道(FIFO 队列),通常与 select 语句相结合使用。

08 Go 运行时比 JRE 更简单

Go 的运行时比 JRE 提供的运行时小得多。没有 JVM 等价物,但两者中都存在类似的组件,如垃圾收集。Go 没有字节码解释器。

Go 拥有大量的标准库。Go 社区提供了更多库。但是 Java 标准库和社区库在功能的广度和深度上都远远超过了当前的 Go 库(毕竟 Java 比 Go 早太多年了,而且生态确实好)。尽管如此,Go 库仍然足够丰富,可以开发许多有用的应用程序,特别是服务端程序。

所有使用过的库都会嵌入到 Go 可执行文件中,即前面提到的静态编译。可执行文件是运行程序所需的一切(而 Java 库在首次使用时动态加载)。这使得 Go 程序二进制文件通常比 Java 二进制文件(单个 “main” 类)大,但当加载 JVM 和所有依赖类时,Java 的总内存占用通常更大。

09 Go 程序的构建过程是不同的

Java程序是在运行时构造的类的合并,通常来自多个源(供应商)。这使得Java程序非常灵活,特别是当通过网络下载时。Go 程序是在执行之前静态构建的。启动时,可执行映像中的所有代码都可用。这提供了更大的完整性和可预测性,部署特别方便,但牺牲了一些灵活性。这使得 Go 更适合集装箱化部署。

Go 程序通常由 “go builder” 构建,这是一种结合了编译器、依赖项管理器、链接器和可执行构建器等的工具。它包含在标准 Go 安装中。Java 类被单独编译(由 Java 开发工具包(JDK)提供的 javac 工具编译),然后通常被组装成包含相关类的归档文件(JAR/WAR)。程序是从一个或多个存档中加载的。档案的创建,特别是包括任何依赖项,通常由独立于标准 JRE 的程序(如 Maven)完成。


其他方面,比如 Java 和 Go 都是过程式语言,此外,在函数式编程方面,Go 一开始,函数就是一等公民,而 Java 8 才有较好的支持。

参考

这个系列主要参考以下资料: