当前位置: 首页 > news >正文

对比Java学习Go——基础理论篇

第1章:为什么Java开发者要学习Go?

Go语言的诞生背景与设计哲学
  • 简单(Simplicity)

    • 继承:Go没有“类”(class) 和传统的继承体系。它使用组合(Composition)接口(Interface) 来达到代码复用的目的,这避免了复杂的继承 hierarchies。
    • 异常:Go没有传统的try-catch-finally异常机制。它通过函数多返回值来处理错误(value, err := someFunc()),强制程序员在每一步都显式地检查和处理错误,避免了异常被意外忽略的问题。
    • 泛型:Go在早期版本中刻意没有加入泛型(直到Go 1.18才引入),就是为了保持语言的极度简单。这与Java强大的泛型系统形成鲜明对比。
  • 高效 (Efficiency)
    • 开发效率:极快的编译速度是Go的标志性优势。Go的编译器直接编译为机器码,大型项目通常在几秒内完成编译。它还有强大的内置工具链(格式化、依赖管理、测试、性能分析等)。
    • 运行性能:Go是编译型静态语言,性能接近C/C++,远胜于Python、JavaScript等解释型/动态语言。虽然在某些计算密集型场景下可能略逊于高度优化的Java/JVM,但其启动速度、内存占用(无JVM虚拟机开销)通常远优于Java。
    • 编译与运行:Java编译为字节码,在JVM上通过JIT即时编译运行,启动慢但长期运行后可以通过优化达到峰值性能。Go直接编译为本地可执行文件,启动即达最高性能,且生成的是一个静态二进制文件,无需安装任何运行时环境(如JVM)即可部署,极大地简化了运维。
    • 内存占用:一个Go程序的内存占用通常远小于一个运行在JVM上的同类Java程序。
  • 并发 (Concurrency)
    • Go的理念:这是Go最核心、最革命性的特性。Go认为并发编程应该是简单、安全且高效的。
    • Java的并发模型:基于线程(Thread)共享内存。创建大量线程开销大,需要通过复杂的锁(synchronized, Lock)来保护共享数据,容易写出难以调试的并发Bug。
    • Go的并发模型:基于CSP理论,其核心是 GoroutineChannel
    • Goroutine:可以理解为轻量级线程。由Go运行时调度和管理,开销极小(初始KB级栈,可动态扩容),可以轻松创建数十万甚至上百万个。相比之下,Java线程是内核级线程,开销在MB级。
    • Channel:用于Goroutine之间的通信,提倡“不要通过共享内存来通信;而应通过通信来共享内存”。这种方式更高级、更安全,能极大地减少竞态条件和死锁的发生。
Go与Java/JVM的对比
  • 原生编译 (AOT)

    • 编译过程:源码 -> (编译器) -> 机器码,Go编译器直接将源代码编译为目标平台(如Linux x86-64)的本地机器指令
    • 运行过程:操作系统直接加载并执行编译好的二进制可执行文件
    • 启动速度:极快,因为没有启动虚拟机的开销,程序直接从入口点开始执行。
  • 解释编译 (JIT)

    • 编译过程:源码 -> (javac) -> 字节码 -> (JVM中的JIT) -> 机器码,javac先将代码编译为中间格式——字节码(.class文件)。
    • 运行过程:操作系统启动Java虚拟机(JVM),JVM加载字节码,由JVM的即时编译器在运行时将热点代码编译为本地机器码执行。
    • 启动速度:相对较慢,需要先启动JVM,加载类,JIT编译器还需要预热阶段来识别和编译热点代码。
  • 部署与依赖:静态链接 vs. 依赖JVM

    • 静态链接:生成一个独立的、静态链接的二进制文件,这个文件包含了程序运行所需的所有代码(包括Go运行时和依赖的库)。
    • 依赖JVM:生成一堆 .class字节码文件和依赖的.jar包。它们本身不能运行,必须依赖目标机器上安装的、特定版本的JRE。
  • 并发模型:Goroutine (CSP) vs. Thread (共享内存)

    • Goroutine:由Go运行时管理的用户态轻量级线程
    • Channel:用于Goroutine间通信的管道,类型安全。
    • Thread:由操作系统内核管理的内核级线程
    • Lock:用于保护共享内存的同步机制(如synchronized, ReentrantLock)。

第2章:开发环境与工具链对比

Java: Maven/Gradle vs Go: Go Modules (依赖管理)
  • Java: Maven/Gradle

    • 核心工具:Maven (pom.xml)、Gradle (build.gradle)。
    • 配置文件:XML (pom.xml) 或 Groovy/Kotlin DSL (build.gradle)。
    • 依赖标识:坐标三元组,<groupId>, <artifactId>, <version>
  • Go: Go Modules

    • 核心工具:Go Modules(go.mod, go.sum),内置于Go工具链。
    • 配置文件:类TOML格式(go.mod) + 校验文件 (go.sum)。
    • 依赖标识:块路径,通常是代码仓库的URL。
  • Java (Maven) 工作流:声明式与中心化

    • 声明依赖:在 pom.xml<dependencies> 节中声明你需要的库及其版本。

      <dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>
      </dependencies>
      
    • 下载与解析:运行 mvn compilemvn install,Maven连接配置的仓库,下载Jar存储到本地。

    • 构建与打包:Maven使用本地仓库中的JAR文件来编译、测试和打包你的项目。

  • Go (Go Modules) 工作流:命令式与去中心化

    • 初始化模块:在项目根目录执行 go mod init <module_name>,生成 go.mod 文件。模块名通常是代码仓库的路径。

      go mod init github.com/yourusername/yourproject
      
    • 声明/添加依赖:在代码中 import "github.com/gin-gonic/gin",然后运行 go mod tidy。Go工具会自动分析代码中的import语句,找到所需的版本(默认最新版本),下载并添加到 go.mod 中。

    • 下载和校验:Go Modules根据模块路径直接访问对应的代码仓库,下载源代码存储到本地。

    • 构建:Go编译器直接使用本地缓存中的模块源代码进行编译。

javac & java vs go run & go build (编译运行)
  • Java 的工作流:编译&运行

    • 编译(javac) :Java编译器 (javac) 读取源代码,进行语法检查、优化,然后将其编译成中间格式——Java字节码。
    • 运行(java) :Java启动器命令会启动一个Java虚拟机(JVM) 进程。
    • 加载:通过类加载器(ClassLoader) 找到并加载所需的 .class 文件(包括你自己写的和依赖的库)。
    • 解释/编译:JVM中的解释器(Interpreter) 会逐条解释执行字节码。同时,即时编译器(JIT Compiler) 会监控运行频率,将热点代码编译成本地机器码并缓存起来,后续直接执行机器码以获得高性能。
  • Go 的工作流:直接生成原生可执行文件

    • 编译并直接运行(go run) :将指定的源代码文件临时编译成一个可执行文件,立即运行这个可执行文件,结束后自动删除。
    • 编译(go build) :Go编译器读取源代码和其所有依赖(包括标准库和第三方库),直接将其编译、链接为针对当前操作系统和CPU架构的本地机器码,并生成一个单一的、静态链接的二进制可执行文件(如 app.exe)。
    • 运行操作系统直接加载并执行该二进制文件,没有任何虚拟机启动、类加载或JIT编译的过程。
包管理:JAR vs 静态链接的二进制文件
  • Java 的 JAR 包 (Java ARchive)

    • JAR包:一个 .jar 文件本质上是一个压缩包,包含了编译好的 .class 字节码文件、资源文件和元数据目录(META-INF)。
    • 运行机制:JAR 包本身不能直接运行,需要在一个已经安装好 JRE的机器上,由 java -jar app.jar 命令来启动。
    • 依赖处理:一个应用程序通常依赖于很多第三方 JAR 包(如 Apache Commons, Spring Framework 等)。
  • Go 的静态链接二进制文件

    • 二进制文件:由 go build 命令生成的一个单一的可执行文件。这个文件里不仅包含了代码编译后的机器码以及三方库。
    • 运行机制:二进制文件直接在操作系统中运行,只需要在终端中输入它的路径即可,不需要目标机器上安装 任何运行时环境。
    • 依赖处理:Go Modules会在你编译时,直接把所有第三方库的源代码,一起编译并链接到这个最终的可执行文件中。

文章转载自:

http://AM5rFHEg.qpntn.cn
http://JpIB7u5g.qpntn.cn
http://MotmVbRx.qpntn.cn
http://kHcNVy8P.qpntn.cn
http://8vPJvEar.qpntn.cn
http://hGkRGKgX.qpntn.cn
http://0zVw0mCf.qpntn.cn
http://bHOFS0ux.qpntn.cn
http://t7IOQLY4.qpntn.cn
http://Tpf8Rfx9.qpntn.cn
http://J7Ry06ZP.qpntn.cn
http://Ov7D8mkN.qpntn.cn
http://SXLWNy0X.qpntn.cn
http://ExuXysOg.qpntn.cn
http://it53OGga.qpntn.cn
http://Zfo0nXdj.qpntn.cn
http://n5Ytp0a8.qpntn.cn
http://TFSPBvqL.qpntn.cn
http://8NFbPA4j.qpntn.cn
http://eQ0EzVi1.qpntn.cn
http://CpPsZsdS.qpntn.cn
http://sGFzgM7m.qpntn.cn
http://ypQQB5Ow.qpntn.cn
http://7el9vCXz.qpntn.cn
http://P5ghGA8x.qpntn.cn
http://jUFD9ddw.qpntn.cn
http://wT0PqHv7.qpntn.cn
http://LmlKWsjw.qpntn.cn
http://BqM9ALub.qpntn.cn
http://4sNOcG9D.qpntn.cn
http://www.dtcms.com/a/371624.html

相关文章:

  • centos9安装sentinel
  • 小迪安全v2023学习笔记(七十九讲)—— 中间件安全IISApacheTomcatNginxCVE
  • 关键字 const
  • 性能优化——首屏优化
  • Linux网络设备驱动程序深度理解
  • Unity AssetBundle详解
  • 小白AIGC短视频生成的第一课之混元AI视频
  • 通义万相wan2.2视频模型的基础模型与安装应用详解
  • JavaEE 进阶第三期:开启前端入门之旅(三)
  • Linux:NTP服务
  • 【多模态学习】QA3:FFN的作用?Embedding生成方法的BERT和Word2Vec?非线性引入的作用?
  • Tomcat 日志文件名的命名规范
  • 基于单片机的可燃性气体泄漏智能报警系统
  • Ubuntu系统下Python连接国产KingbaseES数据库实现增删改查
  • 【linux kernel 常用数据结构和设计模式】【数据结构 2】【通过一个案例属性list、hlist、rbtree、xarray数据结构使用】
  • 论文阅读:DMD | Improved Distribution Matching Distillation for Fast Image Synthesis
  • 深入解析三色标记算法
  • Python struct模块 | 使用pack函数进行字节序打包
  • 二叉树的前中后序遍历(迭代法)
  • Camx-系统默认创建camxoverridesettings.txt
  • SQL面试题及详细答案150道(101-115) --- 数据操纵与定义篇
  • Adobe Premiere Pro(Pr)2022视频编辑软件安装教程与下载地址
  • 18.4 查看订单
  • 【考研C语言编程题】数组元素批量插入实现(含图示+三部曲拆解)
  • 九.弗洛伊德(Floyd)算法
  • pytorch非线性回归
  • Java 大视界 -- Java 大数据机器学习模型在金融市场风险评估与投资组合优化中的应用(407)
  • Python快速入门专业版(十一):布尔值与None:Python中的“真假”与“空值”(附逻辑判断案例)
  • 鸿蒙NEXT应用数据持久化全面解析:从用户首选项到分布式数据库
  • Linux笔记---封装套接字