小玖是奋斗一线的 Java 开发,准备自己开发一个建站程序,出于某些原因,小玖最终将建站程序的开发语言选择了 Go。

对于 Go 小玖其实之前并没有太多接触过,也只能算是个初学者吧,所以对 Go 的 WEB 开发从初学的角度总结经验,希望日后能对初学 Go 语言的小伙伴有所帮助。但本系列不会从零基础开始介绍,是针对有一定程序开发基础的同学,Go 的一些基础语法就不会详细介绍。

一、为什么选择 Go

可能很多伙伴会有疑问,Java 的 SpringBoot 一整套框架做 Web 开发效率高,技术成熟,文档和解决方案都很成熟,为啥小玖要选择 Go 呢?

Go 和 Java 其实差别还是比较大的,这其实是综合考虑的结果,因为 Go 能解决一些小玖认为非常重要的问题,而 Java 却刚好难以解决或者说无法解决。

  1. Java 占用内存高,SpringBoot 框架一启动,直接把内存占满(对小玖的弱鸡服务器跑起来真的非常吃力啦);
  2. Java 的虚拟机机制有些鸡肋,无法动态的去调整内存,比如 -Xmx 等虚拟机参数;
  3. Java 编译的程序需要依赖 JVM 环境,而 Go 编译后的二进制文件可以直接运行(便于建站程序日后的交付);
  4. Java 编译的 Class 容易反编译破解,虽然有一些类似通过自定义 ClassLoader 进行加密的方案,但安全性还是差了很多。小玖了解到的最安全的方案还得是通过 JNI 去调二进制文件做加密和验证,太麻烦了。

基于以上这些问题,小玖找了好久的解决方案,比如 GraalVM 等等的都去了解过,这些方案总是有些局限性,所以,最终选择了 Go。

Go 占用的内存少,而且编译成的二进制文件源码安全性也更有保障。

Go 有以上技术优势,也存在一些劣势,尤其是在生态这块和 Java 差距很大。

二、Java 与 Go 语言上的差异

非 Go 语言专家,只谈谈自己使用以来的一些感受。

Go 的语法比 Java 更简洁

Go 的语法更简短,不像 Java 那么长。但这是次要的,更多的是一种说不上来的感觉,用起来了就会有这种感受。

也许举个例子更能说明这种情况,在 Java 里 try 的语法糖帮助实现了关闭数据流。

try (InputStream bin = getInputStream();) {
  // 各种操作
} catch (IOException e) {
  e.printStackTrace();
}

不用自己关闭数据流,这样用起来就很爽!

而在 Go 中这样类似的语法特别多,就让人用的非常的舒服。举例如 Go 的函数可以直接返回多个参数,接口只要实现了方法就可以自动继承,等等……

Go 的异常处理比 Java 差

Go 的语法中更喜欢直接返回 error 的实体对象,而不是抛出异常。

这就导致了一个问题,在每一个可能抛出异常的地方都要判断一些有没有 error 实体返回,然后再决定是否执行后面的逻辑。

_, err := session.Insert(&param.Site)
if err != nil {
  return err
}

这就导致逻辑里会有很多这种异常判断。

Go 也支持 panic 函数抛出异常,不太明白为啥 Go 不提倡用这个,可能因为异常捕获更加麻烦。

Go 的异常捕获需要用到 defer + recover 一起实现才行。

defer func() {
  if err := recover(); err != nil {
    response.FailWithError(err.(error), c)
  }
}()

Go 的并发处理比 Java 强

Go 的多线程实现比 Java 简洁,并发能力也更强。

不过小玖体会不深,还没有真正自己用 Go 写过复杂的并发逻辑。

Go 与 Java 接口和实体类的不同

Go 的实现了接口里的所有方法就自动实现了接口。实体类叫结构体,与 c 语言的那种结构体相似。

Go 有包的概念,没有太多类的概念,属于同一个包的变量和函数都算一个整体,可以在导入包的时候导入。然后包不能循环导入,A包导入了B包,B包就不能再导入A包了。

三、Java 与 Go 技术框架的差异

Go 的 Web 框架多且乱

目前 Go 主流的 Web 框架有 GinBeegoEchoIris 等等,非常多。

Go 主流的的 ORM 框架有 gormxormBeegoORM 等等……

这与 Java 的 SpringBoot + MyBatis 一套吃遍一圈的套路完全不一样,小玖在刚入门时最大的疑问就是,这些框架有什么不同,他们分别有什么特性?

咨询过很多 Go 的开发,但是貌似没有几个人回答的上来,给我的回答都是这些框架都差不多,大同小异,顺手的选一个用就行了。

Go 的框架更加轻量

小玖也不知道怎么说轻量这个词,往好的说就是程序更简洁,程序启动更快,占用的资源更少。

然后代码上直接主要逻辑,没有用建造者、观察者等等的设计模式,代码量更少,框架里没有各种判断等等复杂的逻辑。

Gin 代码片段

看源码比 Java 的框架轻松好多。

学的老久的 Java 都没把 Spring 摸透,但刚用 Go 小玖就已经可以看懂 Gin 的源码,然后在上面定制功能了。

但往差的说就是 Go 的 Web 框架功能更少,少掉的那些判断和注入逻辑用到的那就是要自己写咯。

比如 SpringBoot 套装用上之后函数上加个注解就可以直观的实现权限校验,而 Go 貌似都是一个一个接口自己做的判断。

四、Java 与 Go 生态的差异

Java 在国内的占有率是非常高的,SpringBoot 一套框架家喻户晓,开发时有各种文档,技术方案上有各种教程,功能实现上 SpringBoot 集成了各种框架自动化配置,遇到问题了还有各种解决教程和大佬解答。

但是 Go 的话,小玖开发这么些天以来,体验并不好。简单的问题会有一些博主的踩坑经验,一些比较深入的问题基本上没有找到有用的相关的文档和介绍,用 Google 也没有什么收获。

Gin 动态删除路由问题

可能,更多时候看源码是唯一的出路。

好在 Go 的框架大都更加简洁,很容易找到关键代码,源码阅读起来相对轻松。

五、总结

总结的话,Java 的生态比 Go 好,在业务系统开发中,很多功能都有 Java 有很成熟的解决方案,开发速度快且稳定,就算遇到问题了也能找到前人的案例,能够快速解决。

Go 的话性能更优秀,更适合做一些偏底层的应用研发,然后也更方便对外交付。

以上,个人的理解!