这篇文章需要对java和go有一点了解才好,如果不了解,可以直接跳过
目录
语言对比
因为本人以前学java的,所以难免就会好奇java跟go有什么不一样的。
① java是基于C,C++的。而golang是自举的
② java中协程概念不明显。而golang本身就是基于并发的,所以语言层面就支持并发
③ java体系非常完善,其各种技术和产品非常多。golang作为新生语言,目前也趋于完善,不过按成熟程度还赶不上java
④ java中的jvm优化(屏蔽)了很多的细节。golang也优化了很多,不过很多主要的还是保留了下来
⑤ java都是class(类)作为对象的。golang使用struct(结构体)作为对象的
⑥ java没有指针和地址的使用方法。golang保留了指针和地址,不过相较于C语言还是阉割了很多
golang的数据类型
绝大部分的基础数据类型是跟java基本一致的,所以其申明使用就不讲了。我想主要说一个类型(channel严格来说是并发的,所以这里不说)slice切片。
如果非要把golang的切片对应java的话。那arraylist较为贴切了,从我目前感受来看,几乎完全一致,当然我是刚学,感受不深。如果有区别请不吝赐教,非常感谢。
我们先看一样的代码:
go实现:
func Test_slice_1(t *testing.T) {
//申明切片,并初始化
s := []int{1,2,3,4,5,6,7,8,9}
//截取一部分
s1 := s[1:3]
//设置元素
s1[0]=0
//打印原切片
fmt.Println(s)
}
java实现:
public static void main(String[] args) {
//申明list
List<Integer> list=new ArrayList<>();
//初始化list元素
list.addAll(Arrays.asList(1,2,3,4,5,6,7,8,9));
//截取一部分
List<Integer> subList = list.subList(1, 3);
//设置元素
subList.set(0,0);
//打印原list
System.out.println(list);
}
那么切片是为了解决什么问题的呢?
首先需要先了解数组,切片的本质也就是数组。所以切片必定是为了解决数组的弊端而存在的。
数组弊端:
1、一旦初始化,长度就必须固定。不可更改。
2、如果想要做一些数组的操作(比如截取一个片段),必定很消耗资源。
切片的出现就是为了解决这类问题出现的。有了切片那就可以自动扩容,类似于截取的操作其实也就是在原切片上操作,这样避免了大量的复制。
框架对比
java: java几乎有一套标准的框架spring。现今几乎所有的框架程序都是基于spring做的开发,它的优秀不可否认。
golang:go就没有java那种公认的标准的框架,几乎所有框架都有自己擅长的领域,但是像比较出名的web框架和orm也并不是特别多。
协程的由来
我是参考这篇博客的:https://www.cnblogs.com/xuanyuan/p/13824621.html
还有篇博客也不错:https://www.cnblogs.com/secondtonone1/p/11803961.html
协程的概念其实很早就有了。但是几乎只有新兴的语言支持,像java就基本都有协程的概念,依旧使用线程池(threadpool和forkjoin为主)。那么为什么以前的语言都没使用协程呢?
最近几十年都是计算机的高速发展期。比如在200几年的时候计算机的CPU并不强大,而且计算机本身发展也不好,所以几乎使用线程就能解决了,还没有到要使用协程地步。
但是,经过几十年的高速发展,我们的计算机的性能有极大的提升,而且高并发的场景也越来越多,那么对于网络来说也会存在极大的开销。这样即使一直优化也很难充分利用CPU。举个例子:
以java为例:
假设我有一个线程池:
刚好线程池接到了一批线程都是非常大额网络io
按照线程池的情况,那么就是一直等着io传输完毕才能接着执行任务
然而io期间cpu却是一直空闲的,极大的降低了CPU的利用率,明明我可以使用这个空档利用CPU去做更多的事情。更加充分的利用CPU。
所以协程就诞生了,协程也称为轻量级线程。
诚然,我们没法干预操作系统对线程的调度,但是我们能够自己在用户程序去管理协程(比如遇到sleep,文件读写,网络传输等就在用户进程中去切换用户上下文去做其它事情),使其充分利用CPU,从而高效运行。
go天生支持协程的特性是我觉得这是相较于java最大的一个优势,没有之一。