题目序号:(1066,1753,1787,1794,2825,3981,4080,5350,5650)
题目来源:七牛云、猿辅导、蚂蚁、知乎、百度、虾皮
频次: 9
答案:(Zbbxd)
1、函数重载
Go不允许函数重载,必须具有方法和函数的唯一名称。java允许函数重载。
2、封装
Java:class 关键字组织对象,所有方法和字段都定义在类内。
Go: struct 关键字组织对象,struct内可以有字段和方法(方法组织形式不是字节在struct内声明),也允许方法和字段脱离方法之外,这些方法属于包。
3、多态
Java通过类继承或接口来实现多态;Go 只能通过接口来模拟实现多态。(Java默认允许多态。而Go本身不支持多态。)
Go并不是面向对象的编程语言,Go不像Java、C++有类的概念,但可以基于结构体来实现类和类的方法的概念。
Go本身不支持多态,Go 语言的结构体明确不支持像Java这种形式的多态,外结构体的方法不能覆盖内部结构体的方法。但面向对象的多态性可以通过 Go 的接口特性来模拟。
4、访问权限
Go语言通过大小写控制包外可访问还是不可访问。(首字母大写是公有的(public),首字母小写是私有的(private))
Java通过访问修饰符(public、private、protected)来控制变量、方法或类的访问权限。
5、接口
Go:Duck typing方式,在使用时抽象出接口,有点先实现后抽象。Go 的 interface 写起来更自由,无需显式实现,只要实现了与 interface 所包含的所有函数签名相同的方法即可。
Java:提倡先定义,后实现。J需要在类的定义上显式地使用关键字实现了某些接口(implements),才可以说这个类具备了接口定义的能力。
在Go中实现接口并不需要使用类似于 Java 语言的 implements 关键字,结构体和接口会自动产生关联。
6、继承
Java的继承通过extends关键字完成,不支持多继承。
Go语言的继承通过匿名组合完成:基类以Struct的方式定义,子类只需要把基类作为成员放在子类的定义中,并且可以通过调整基类成员的位置改变内存布局,支持多继承。
7、值引用和地址引用
Go:所有对象默认是值应用,在对象前加&表示地址引用。
Java: 基础类型是值引用,其他对象是地址引用。
8、异常处理设计
Go语言没有类似于Java、.NET中的异常处理机制,虽然可以使用defer、panic、recover模拟,但官方并不主张这样做。Go语言的设计者认为应该在设计开发的时候充分考虑使用场景可能出现的情况,处理好已知和未知的错误与异常。
9、协程
协程是 Go 语言作为并发编程语言最为重要的特色之一,协程用起来比线程更加简单,占用的资源也更少。通常在一个进程里启动上万个线程就已经不堪重负,但是 Go 语言允许你在单机上启动百万协程也可以轻松应付。
Java并没有从语言层面默认提供协程的实现,而是更多靠社区第三方的协程类库。
10、垃圾回收
Java基于JVM完成垃圾收集的功能,其体系很庞大,包括了垃圾回收器(G1、CMS、Serial、ParNew等)、垃圾回收算法(标记-清除、标记-整理、复制、分代收集)、可达性算法(可达性分析、引用计数法)、引用类型、JVM内存模型等内容,目前Java在JDK 1.7开始使用G1垃圾收集器来进行垃圾回收,其特性及回收过程大致如下:
Golang则采用三色标记法,主要流程如下:
- 所有对象最开始都是白色
- 从root开始找到所有可达对象,标记为灰色,放入待处理队列
- 遍历灰色对象队列,将其引用对象标记为灰色放入待处理队列,自身标记为黑色
- 处理完灰色对象队列,执行清扫工作
11、并发编程
在Java中,通常借助于共享内存(全局变量)作为线程间通信的媒介,但在Golang中使用的是通道(channel)作为协程间通信的媒介,这也是Golang中强调的:
不要通过共享内存通信,而通过通信来共享内存
在Java中,使用共享内存来进行通信常会遇到线程不安全问题,所以我们经常需要进行大量的额外处理,方式包括加锁(同步化)、使用原子类、使用volatile提升可见性等等。
CSP的指的是是Communicating Sequential Processes (CSP)的缩写,中文为顺序通信进程。CSP的核心思想是多个线程之间通过Channel来通信(对应到golang中的chan结构),这里的Channel可以理解为操作系统中的管道或者是消息中间件(不同之处在于这个MQ是为不同协程间服务的,而不是进程)
说到了CSP就得提一下Golang自身的并发模型MPG,MPG中M指的是内核线程、P指的是上下文环境、G指的是协程,其中M与P一起构成了G可运行的环境,M和P是一一对应关系,通过P来动态地对不同的G做映射和控制,所以Golang中的协程是建立在某个线程之上的用户态线程。