学习Golang,Java,C++区别

(文章有点长,算是个人学习的一个小总结,大家如果有耐心看完欢迎提出意见)

Golang处在Java和C++中间,他有着比Java更快地性能,也有比C++更方便的开发方式,但Golang在很多方面还是跟Java有些雷同,我们来看看三者中间的差别和相似之处,然后着重看看Golang和Java的异同。

三者的不同

1.语言类型和平台
1.1语言类型

语言类型分为编译和解释,顾名思义,编译型语言就是把所有的代码一次型编译,然后运行,而解释型语言就相反的,是一句一句的编译解释运行。

Go语言和C++语言一样是编译型的静态语言,所以在运行Go和C++程序之前,先要将其编译成二进制的可执行文件。

所以像C++我们安装的MingGW其实就是C++的编译器,帮助C++实现编译的。

而相对而言的,Java就是可以说是编译型语言也可以说成是解释型语言,首先Java会将所有代码编译成.class文件,这个过程是编译过程,所以Java可以说成是编译型语言,然后.class文件会被放到虚拟机上解释运行,也就是说一句一句从.class文件解释成机器能明白的语言,然后运行。

这里的差别就是编译型语言Go或者C++是直接将语言编译成机器能懂得文件,然后就可以直接运行了,而Java有了.class这中间一步,这个文件是机器看不懂的,所以要在JVM上再加一步解释

从这个方面来看,C++和Go的代码运行性能是比Java快的,毕竟编译型语言比解释型语言块要很正常。

1.2平台

在C++比较有受欢迎的事linux编程,这个问题就导致如果我们在windows的环境上写关于linux编程的代码,比如最简单的在进行网络编程的时候

在linux环境上的包是sys/socket.h

而对于windows上的包是winsock.h/winsock2.h

所以如果我们在windows上开发的网络编程代码,要部署到linux系统的服务器上去运行的话,这是肯定行不通的,而java和go没有这个问题。

java我们都清楚,他是有java虚拟机的,也就是说不管你代码到哪个系统,所有代码其实都是运行在虚拟机上的,所以就没有系统差异一说。

而Go和C++一样是编译型原因,但是Go也是可以跨平台运行的语言,但是Go又不像Java一样需要虚拟机这样一个中间过程,

Go这个实现跨平台的过程,我的简单理解是

  1. 一个是Go没有Windows和Linux区分的工具包,这个是关键
  2. Go在编译的时候可以选择需要运行的平台SET GOOS=linux // 目标平台是linux,如果是window那么这个参数设为darwin
2.内存管理

GO和Java一样有内存管理机制,也就是Java中常见的垃圾回收,在Go里面也有,而这一点是C++没有的,也是C++不方便的一个方面,因为程序员需要时刻的去记住创建之后要释放内存。这个在后面写Java和Go的区别重点学一下

3.语言特性

Go是不支持类与类之间的继承关系的,在go语言里面,有对象和接口的概念(刚入门的个人理解,后面有更深的理解了再来补充)

一般来说,最好一个文件.go就是一个类,当然也可以放多个struct来放在一个文件里然后用func(*className)来实现多个类的方法
所以go的类的属性和方法是分离开的,如果一个文件是一个类方法集中在interface中申明可以系统一点,(当然不申明也可以用func(*className)实现),然后一个一个实现。

举个例子,我们要实现一个学生类,其中属性包括,姓名,年龄,性别,方法包括,写作业,考试,我们可以写成这样

import "fmt"

//方法接口应该是类名的首字母大写
type Student interface {
	DoHomework()
	TakeExam()
}
type student struct {
	Name string
	Age  int
	Sexy string
}
//提供初始化方法
func NewStudent(name, sexy string, age int ) Student{
	return &student{
		Name: name,
		Sexy: sexy,
		Age: age,
	}
}
//接口的实现
func (s student) DoHomework() {
	fmt.Printf("I'm doing my homework")
}
func (s student) TakeExam() {
	fmt.Printf("I'm taking an exam")
}

得到一个这样的类之后,我们可以通过这两种方法去实例化并使用这个类

package main

func main()  {
	var stu student
	stu.DoHomework()

	stu2 := NewStudent("s", "男", 10)
	stu2.DoHomework()
}

go每个类之间都是独立存在的,接口也仅限于当前文件内,类与类之间并无父子继承关系。

go不允许重载但是允许重写,重载和重写看这个,但是go的重写其实不是严格的重写,因为他并没有父子的继承关系,只是如果在同一个文件内有多个类的话,类于类之间的函数名可以重复。比如下面这样

import "fmt"


type student struct {
	Name string
	Age  int
	Sexy string
}

type teacher struct {
	
}

func (t teacher)TakeExam()  {
	fmt.Printf("I'm taking an exam")
}
func (s student) DoHomework() {
	fmt.Printf("I'm doing my homework")
}

func (s student) TakeExam() {
	fmt.Printf("I'm taking an exam")
}

java和C++中的函数重载和重写就不写了,因为他们都支持。

4.开发性能与效率

高质量的C++代码性能依旧是最猛的,这个无可厚非,Go其次,毕竟编译型语言比解释型语言的优势在那。

(仅限于了解过的框架,有经验的大佬可以给我提提意见,我去学习一下)
Go写开发代码的时候,比如go-kit框架,没有了SpringBoot那种特别多的配置文件,还有各种@关键字,用go-kit做开发的话就完全是三层架构,并且这个架构只是工具包并不是框架,所以用起来简单许多。

在多线程方面,Go的go routine创建的是协程,协程又是轻量级线程,所以效率肯定比线程块,并且只需要go + xx就能开启一条routine,比Java的多线程要方便不少。

Java和Go的区别

go有着和c++媲美的速度,当然,c++呗程序员诟病的内存管理,go肯定要进行优化,所以go自己也有属于自己的垃圾回收机制,其中Java也有,,所以我们看看Go的垃圾回收跟Java有什么区别

垃圾回收

Java垃圾回收

Java垃圾回收机制

Go的三色标记法

三种颜色:白色,灰色,黑色
白色为这次垃圾回收需要处理的对象,灰色为下次处理需要进行遍历的集合,黑色为本次不能清理的对象。

  • 一开始所有对象都为白色
  • 从root开始找到所有可达对象,标记为灰色,放入待处理队列
  • 遍历灰色对象队列,将灰色对象引用的对象标为灰色,自身标为黑色
  • 处理完灰色对象的队列,执行清扫工作

Go GC的流程:
在这里插入图片描述

  1. Stack scan: 收集跟对象也就是我们说的能作为root的对象,开启写屏障,写屏障需要STW、
  2. Mark:标记所有根对象和根对象能到达的所有对象,这些对象不能被回收
  3. Mark Termination:重新扫描全局变量,和上一轮改变的stack(写屏障),完成标记工作,这个过程需要STW
  4. Sweep:按标记结果清扫span

TO BE CONTINUE…

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值