好像很多语言的程序包执行都需要相应的环境,除了脚本类的,Java 这种需要编译的,好像经常也是 java -jar abc.jar 这种,而 go 语言能直接编译出不依赖 go 环境的包。可以帮忙提点一下吗盆友们,关于这个问题,应该往哪方面去了解?
好像很多语言的程序包执行都需要相应的环境,除了脚本类的,Java 这种需要编译的,好像经常也是 java -jar abc.jar 这种,而 go 语言能直接编译出不依赖 go 环境的包。可以帮忙提点一下吗盆友们,关于这个问题,应该往哪方面去了解?
1
seers Jul 15, 2020
解释型编译型?不过 Java 也要编译但是还是依赖 jvm
|
2
HiShan Jul 15, 2020
graalvm 了解一下
|
3
sulinehk Jul 15, 2020 via Android 可以进行自动垃圾回收的语言都需要一个运行时环境,只不过 Go 是把这个运行时打包到二进制文件里,而 Java 显示使用这个运行时。
|
4
ChanKc Jul 15, 2020 via Android
aot 和 jit ?
|
5
lower Jul 15, 2020
操作系统原理、编译原理、计算机组成原理
|
6
monkeyWie Jul 15, 2020
graalvm +1,不过静态编译限制比较多,反射类加载就不好用了
|
7
BingoXuan Jul 15, 2020 java 编译出来的是通用的字节码,扔到不同平台的 jvm 内就能运行,实现 compile once, run(debug?) everywhere 。
go 编译出来的是不同平台的机器码,不同平台只能运行对应二进制文件,实现 code once, compile for everywhere |
8
sonxzjw Jul 15, 2020
1.java 也可以打包成二进制执行程序,要找工具,有不少缺点;
2.java 的创始人的层面就是这样的理念,用 jvm ; 其实这些很多都是跟语言创始人的理念、多方面考虑而定的。 |
9
zjsxwc Jul 15, 2020
只要 jvm 在目标平台可以跑就行,大不了发布的时候把 jvm 也带上不就好了
|
10
tlday Jul 15, 2020 Java 最初就是作为编写放进一些家电设备中的嵌入式编程语言立项的,在这种条件下,你要求这些家电设备内置一个桌面级运行环境是很奢侈的,那可是 1991 年,桌面级运行环境作为嵌入式设备的平台?那个时候还不是这三家独大,有各种奇奇怪怪的系统和平台。相反,你制订一个标准让对应的硬件平台厂商去实现,要更符合那个时代的主旋律。
而且将 runtime 直接放进应用程序这种想法在当时的带宽条件下是个正常人都不会有的。大家肯定还记得在智能手机出现以前,一些支持 J2ME 平台的手机,一个几百 k 的 jar 文件中能有多丰富的游戏内容。如果你把 runtime 也打包进去,那是不可能那么小的。你看 Windows 到现在还在发布.Net 你不能现在只看得到 JavaSE 和 JavaEE 就忽略 J2ME 才是 Java 最早的初衷。 |
12
dakb Jul 15, 2020
因为 java 是跑在虚拟机上的语言。go 是直接编译成目标文件的语言。
|
13
DJQTDJ Jul 15, 2020
建议楼主私信 James Gosling,我想如果他有时间的话,应该会告诉楼主为什么把
https://twitter.com/errcraft |
14
janxin Jul 15, 2020
不要这样,Java 其实也可以的,GraalVM 了解一下
|
15
Rwing Jul 15, 2020
.NET 欢迎您
|
16
libook Jul 15, 2020 不知道什么课程里会包含这些知识,计算机导论?感觉只要是科班出身的都自然而然地了解这个。
大学课程里最初是会将编程语言分为: 机器语言:二进制指令 低级编程语言:汇编语言 高级编程语言:C 、C++、Java 等等 然后高级编程语言大体上又可以分为: 编译型语言:C 、C++、Java 等 解释型语言:JavaScript 、Python 、PHP 等 编译型语言又可以分为: 直接编译成平台机器码的语言:C 、C++、Go 等 编译成虚拟机机器码的语言:Java 、C#、WebAssembly 等 以上只代表各个语言的常规使用方式,实际上语言只是语言,设计不同的编译和运行机制,可以让一门语言以不同的方式来操作计算机运行,比如使用特定的编译器可以将 Java 直接编译成机器码,不依赖 Java 运行时就可以运行,C 也可以编译成虚拟机机器码,在虚拟机上运行。 Java 的可执行程序本身不携带 Java 运行环境,这个其实是 Java 的设计初衷,以及其最大的卖点:“Write once, run everywhere”。因为早先的编程语言都需要编译成对应平台的机器码才能被正确运行,比如想在电脑上运行就编译成台式机平台的程序文件,想在手机上运行就编译成手机平台的程序文件,而如果电脑和手机采用的 CPU (指令集)不一样的话,对应电脑平台的可执行文件无法在手机上运行,而且编译成不同平台的程序文件很可能需要改动大量代码。(这个就不展开介绍了,想了解可以去学习一下计算机组成原理和汇编语言。)然后 Java 率先实现了写一份代码、编译成一个可执行文件,可以在任何被 Java 运行环境支持的设备上运行,Sun 公司负责开发出支持各个设备的 Java 运行环境。这对于需要程序支持多个硬件平台的开发者来说,几乎完全免除了兼容多个设备需要做的大量工作(至少在当时是)。 |
17
passerbytiny Jul 15, 2020 via Android
Go 是用来替代 C ( C ++)的,为何要跟 Java 比较。
|
18
Kilerd Jul 15, 2020
@passerbytiny #17 Go 用来替代 C ?
|
19
dhssingle Jul 15, 2020
@passerbytiny #17 因为实际跑起来,效率还不如 C# 和 Java,拿什么去替代 C 。
|
20
wysnylc Jul 15, 2020
Java 可以,只是不建议用
Go 是只能打包成二进制文件,没有其他选择哦 |
21
jizhihaoSAMA Jul 15, 2020
@passerbytiny 替代 C cpp 写服务端吧,其他的替代不了
|
22
koebehshian Jul 15, 2020
编程语言只规定了语法,编译器或解释器是对编程语言的实现,一种语言可以有多种实现。
|
23
DoctorCat Jul 15, 2020
抛开原理,说个分发方面:
Go 把依赖都打包在一个可执行体里了(编译后都是机器码不需要 VM,runtime 部分尺寸相对 Java 运行时要小得多,分发起来轻便) Java 有一整套的 VM 依赖和其他框架的库依赖(编译后是字节码必须在 JVM 上执行,依赖尺寸太大,所以分开了好。分发起来应用与 VM 独立比较好)。 |
24
c2const Jul 15, 2020 via iPhone
go 编译后其实带一个很小的运行库,不过是集成在一起了,和 java 在语言设计之初就不一样。
Java 也有 aot 编译,不过因为语言设计之初的目的,而且现在 java 也太臃肿,做 aot 编译的项目和公司基本都凉了,或者很久没更新了。 最新的商业软件好像是可以支持到 jdk1.8,前几年那公司也倒闭了。 技术原理大概就是 0,把与 jvm 无关的逻辑代码转成汇编(现在有 llvm 方便很多), 1,与虚拟机耦合不深的 native 方法(比如数组拷贝),一般是重新实现一份 2,与虚拟机耦合深的方法(比如获取虚拟机启动时间),一般做法还是需要启动一个最小虚拟机 3,特有语法特性,比如 反射、动态改字节码、jvm 上其它语言的函数式编程……都是大坑 不过计算机的事,没什么是加中间层不能解决的。 |
25
fengyj Jul 15, 2020
@passerbytiny #17 你说 rust 替代 c/c++我还行,go 就算了。
|
27
c2const Jul 15, 2020 via iPhone
@huiyifyj 仅个人感觉,go 是抢 c/c++的服务端市场。rust 微软再推,抢 c/c++操作系统、内核组件、安全是为了防止内存泄露相关的漏洞利用,主要还是安全领域相关的吧
个人不太喜欢 go 语法,c/c++真香:) |
28
gz911122 Jul 15, 2020
java 也可以的 graalvm 了解一下
先问是不是再问为什么 |
29
auin Jul 15, 2020
"而 go 语言能直接编译出不依赖 go 环境的包"
Go 把运行环境编译进了二进制包! |
30
flynaj Jul 15, 2020
go 出生比较晚,以前一些没解决的需求不解决,还有更好的性能。多核心支持的话,不会有人用的。
|
31
sunziren Jul 15, 2020
同意楼上的,我也有这个疑问,建议你直接问发明 java 的那个人。
|
32
locy Jul 15, 2020
java 文件是编译成字节码,字节码!=机器码,字节码是在虚拟机上执行的。
|
33
Tink PRO 看一下 编译原理
|
34
tairan2006 Jul 15, 2020
时代不一样了,云时代 go 确实有部署优势
|
35
chihiro2014 Jul 15, 2020
Go 就算了。。。
|
36
systemcall Jul 16, 2020 via Android
时代不一样,Java 出来的那个时代,CPU 指令集和 OS 都五花八门,迫切的需要一个不用重新编译就可以跨平台的系统。当时许多设备的内存是以 KB 来计算的,用 XiP 来运行。0 几年也是这样。以前 Java 用的多的地方基本上就是现在安卓用的多的地方
Java 编译成二进制是可以的,针对平台优化也是可以的,但违背了 Java 的初衷,不过现在也没多少人提了吧。安卓里面用户也不能够直接运行 j2me 应用了。现在的指令集和 OS 就那几个,真是方便 |