`
joeytang
  • 浏览: 8037 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java转go的这些天

 
阅读更多
听说go是很久以前的事了,在2018年的时候周围有些哥们开始用go,听到的更多了一些。2019年底有幸加入go技术栈的公司,终于在go门前推了自己一把。在门前徘徊的这些日子里,总是想到刚学java时候的压抑、蛋疼和无数个通宵的夜。要不是有个漂亮的师姐,无微不至的帮助,真觉得不会干这行了。啊,错了不是师姐,是个师兄^_^。因为恐惧所以徘徊,也正因为这段时间的徘徊,才让我这段初次接触go的旅程收获了非一般的惊喜和开发体验。这篇文章不是介绍java和go的对比,不是神化go,不是劝你抛弃java拥抱go。是一个java开发人员开始使用go的一些琐事和一点感受。

  • 1、缘起



菩萨畏因凡人畏果。任何事情都有起因。这个也是指引你的原力。
最直接的原因公司是go技术栈的,短期内没有必要多语言栈并存。好吧 可以认为是一个被动的原因。在这个被动原因之前其实已经几个哥们引诱了好多次。我们之前的圈子基本上都是一群java的油腻大叔(写了比较久的java),慢慢聊起go的话题开始多了起来。可能是go的发展真的很快,尤其在国内go的环境真是被这些大公司给带起来了。一些朋友开始尝试用go,后来慢慢又有好一些人开始用go,这些人用了go而且给的反馈都还挺好,慢慢的我也被吸引了。
“go性能高”、“协程真的很棒”、“channel有意思”、blabla 好吧 那就用用吧。说的这么多我其实没有感觉,对我来说一直认为自己的java是停留在上层应用,每次往底层分析的时候都会受限于自己的水平。曾经天真的以为只要能写应用就可以了,不需要往深了了解,过几年就会发现这个想法"Too young too simple,sometime naive"。听说go比c又上层一点,那正好作为一个往深一层学习的一个台阶。
java丰富而高深的框架真的不错,于是很想写写框架,可是已有的无数的框架绝对给你啪啪打脸。听说go还没这么多框架,嘿嘿是不是又可以尝试一下了呢。
再者技多不压身,java一个姿势久了,是不是可以换个姿势呢。一种新的姿势,给你一种新的视角来审视自己。
于是那就go起来吧。

  • 2、初识



与go的初次见面和java截然不同,之前学java是先看书学习,边学习边demo,慢慢开始写功能。这次接触go直接就是上业务功能(这个办法真的很有效),记得是要对接短信服务商,没错就是用户注册、登录、忘记密码时候发的短信。
因为是线上业务还是p0的,绝逼不能写出问题了,要不写出问题就得知道这块功能涉及到的语法别写错了。先看看公司已有的代码怎么写的,依葫芦画个瓢,那也得知道用什么笔用啥颜料。当然功能也比较简单很快功能就写完了,慢慢灰度上线,没出啥问题。现在还在用着当时写的代码。这个时间用的不长不短,得有三天吧。相比较最开始写java那是快了很多,想写个hello world,装tomcat、jdk打包部署,浏览器里请求出结果来,没有个一星期是出不来的吧。可见go的语法之简单,打包之便捷。刚看到go的语法可能会让你有点小奇怪,为啥类型会在参数后面,这个你可能会一直耿耿于怀,其他的整体上都没有什么陌生感。基本类型、数组、slice(像java里的List)、map每个类型的常用方法也都很相似。当时用到go里的闭包是还是有点小兴奋的,之前非常喜欢JavaScript觉得用函数做为变量传来传去真的爽,还有之前groovy(这个感觉快要跪了)用过类似的闭包,终于又可以尝试了。
除了语法上的入手简单印象比较深的还有http请求的处理以及json的处理。
功能上做的是对接第三方短信通道,少不了要http调用别人的接口以及入参出参的json数据处理。我相信用java的一定会用httpclient,然后就是看到各种被横线划掉的方法(Deprecated),httpclient的版本变化真的太让人猝不及防了,怎么用也是一天一个样。那要是用java自带的http处理,感觉又很无力。用go的时候曾经想过是不是也要依赖第三方,说实话还有点小担心的,万一像httpclient那样,这个功能不知道要写到啥时候了,看了已有代码放心了很多,是go自带的客户端,入参出参比较清晰,也是类似httpclient的参数包装,代码写起来很简洁。http请求结果需要将返回值转成对象,java时候怎么处理的呢,使用的fastjson还是jackson,还得配置一些特殊的参数之类的,在这里还是go自带的包,特殊处理用对象上的标签,当然也可以不用配置 使用规约大于配置就好了。http处理和json的处理两个小小的点吧,让我感觉用起来比较简单。
跟go的第一次会面总体还是比较顺利。打破了之前徘徊时的恐惧。听说go性能很好,于是尝试用go解决一个小功能。之前有个事情需要对50G左右的图片文件进行裁剪、压缩、打水印,使用了java一个第三方包开多线程尝试了一部分图片的处理,算了下时间整体下来可能要2个小时左右。那用go试试吧,记得是一顿开协程,竟然十几分钟全部跑完了,当时有点惊讶,也初次感受到了大家津津乐道的go的性能,虽然是一个小尝试,在没有各种调优的基础上还是能窥得go性能的一斑。

  • 3、修炼



实现了一个小的功能,学习了一点小的语法,尝到了一点小的甜头,接下来有勇气真正上路了。需要实现的功能接踵而至,遇到的陌生语法也开始越来越多,公司已有框架的代码也开始越来越难看懂。细想下来还是基础不牢靠,还是应该系统的学习下go的基本知识。在前人的指导下跟着一本电子书从头看到尾,索性章节不多,去掉代码也没多少文字了,每天看一点,语法熟一点,至少知道go里都有哪些可用的类型,在遇到合适的场景知道搬出来用,具体使用的细节 可以再找例子仔细研究。我属于比较懒的那种,就看了一本电子书后面就开始了真正的业务开发了。时间上算从0开始边做功能边学习,经历了两周的时间,基本上业务功能开发需要的入门知识基本上都没问题了,就这样在接下来半年时间前前后后做了三个系统,也尝试的写了一些基础框架的东西,基本上之前java能够做的事情,目前用go都是可以做了。这只是修炼的最最基础系统学习基础知识。
有了基础知识,写高深代码有点难,但是看还是能看懂的。现在公司都是微服务的架构,微服务配套的框架在工作中会非常重要,需要一点点看懂公司现有框架到底怎么实现的。服务治理、注册发现、配置中心、服务关系...这些主题的处理原理大致相同,实现方式各有千秋,跟着源码看看具体实现会感受到go实现的风格真的不同。印象比较深的就是各种连接池的处理非常简单,之前写java时只要涉及到池化的代码都是非常谨慎而且代码量也比较大,go因为有了channel的使用对池化的处理简单多了。另一个印象较深的就是思路的不同,go在共享数据的处理是异步化的思路,使用通过channel给使用方传达指令,java的思路主要还是用锁,go里也有java中对应的锁,开始总是喜欢用锁的思路,也能实现类似的功能,但是写出来的代码总是比较别扭,经这边大神review几次代码并且讲了go在这块的处理思想慢慢的开始了解并接受这种新的视角,现在更喜欢上了这种处理方式。
多看看公司现有的代码,仿照着写,并且想大神请教原理,慢慢的自己写的代码也开始有了go的味道。这个过程是重复循环的,会多次的学习基础语法,经常又去看现有代码,然后用到自己写的代码中。如此的反反复复,慢慢让自己的代码和公司已有的代码比较能融合。
可能你会问我这样太过守旧,不能破陈出新。是的,作为一个刚入门的go人员我觉得还是没有批判和挑战的本事。先能搞明白“是什么”,“为什么”,再去想“为什么不”更能让人信服。

  • 4、反噬



就像武侠小说里说的那样内功修为不够,强练高深武功很容易遭到反噬。我也不例外。在基础不牢的情况下修改了公司里的框架,而且导致了线上的进程崩溃,这次的教训还是比较深刻的。事情不复杂简述之。有个通用配置放到了内存中用map存储起来(key是固定的几个),有一些场景会更新map数据,有些场景是读这个map。在java中我们使用concurrenthashmap,甚至用map也不会有太大问题。于是就想当然的用了go的map。结果并发场景直接会panic,导致整个进程死掉。而当时出问题的时候,我还一直认为是偶发性的,出现这种问题的可能性很小,结果到了高峰期就成了必现问题了。正好这个是放到类似网关层的代码里,可想影响范围了。不过好在mentor经验比较丰富,第一时间处理了这个问题,防止影响的扩散。故事是不是和修炼武功走火入魔,然后高人出手一顿疗伤保住小命的情节如出一辙。事故的原因现在很好分析就是go是不允许共享的数据的读写,遇到并发时会直接导致panic,panic如果没处理就会导致整个进程down掉。这其实是一个很低级的问题,也暴露出来基础的薄弱,需要打好基础。经过这次以后也关注了一些go和java的不同,也了解到go有些让你使用起来会比较蛋疼的事情。其他高深的对比主题请自己搜索。仅列举个人写代码觉得不是很爽的地方。一个就是上下文信息的传递。之前写java框架包装的时候,大量的上下文参数都是基于threadlocal,然后结合反射,动态代理,这样框架包装对使用方来说是透明的,不会有任何影响,如果我们控制好框架的版本,我们可以在使用方完全无感知的情况下埋各种点。在go里是没有这个东东的,而且建议不要尝试自己封装一个threadlocal,因为go这是协程,原理上就不太一样。官方的推荐是方法上加一个context对象。是的所有的方法中有个context入参。所以你看到很多代码里有context请不要被吓到,而且请务必要仿照着写,否则以后加框架的时候所有方法再重新补上context那是一个很惊人的操作。还有一个难受的特点就是没有泛型。java从1.5之后的泛型(虽然不是真正意义的泛型),让写业务代码,尤其是写框架的时候抽象处理方便很多。刚用go的时候总想用泛型的思路,然后就查查网上针对这个事情的各种争吵,都有各自的道理,go加不加泛型我们的代码都得写啊,所以先在现有的方式下写自己的代码吧。

  • 5、远行



修炼的时候我们关注go的基础知识,以及公司已有的代码框架学习。当这些都熟悉之后,我想已有的代码应该已经不能满足你了。那就开始看开源的框架代码吧。框架很多了,可以围绕几个大的主题去看框架。从微服务的角度看可以看看rpc框架、日志框架、配置中心框架、调用链框架、缓存框架、数据库操作框架、mq框架、监控报警框架、网关框架、熔断限流降级框架等等,从业务开发角度可以看看mvc框架、orm框架等等。当然还有很多别的主题的框架,就根据个人喜好到处搜刮搜刮。看别人的代码,模仿着写写,慢慢内化成自己的代码风格。这个过程会很长久,算是更深层次的修炼了。路漫漫其修远兮,吾将。。。起步(*^▽^*)

  • 6、归心



在是否转go和怎么转go的问题上,我认为一直都要问问自己的初心。有人是因为兴趣使然,有人是客观原因不得不转,哪一种理由都是合理的,也是一直能推着你走下去的动力。从上面琐碎的叙述中,我想转go,至少从java转go,还是非常容易的,最困难的是你想明白自己的意愿还有克服对未知事物的恐惧。转的过程一定会遇到一些问题,尤其是一个人自己默默的转,遇到问题解决周期很长,效率低下而又打击积极性,但是如果能在牛逼的团队里,想想在go上你遇到的哪些问题会解决不了呢。如果不推自己一把,一直徘徊在go的大门外,我们都清楚一定学不好的。最后推荐一个好去处,伴鱼后端开发,全go技术栈,优质mentor的陪伴,让你轻松无痛入手go。

分享到:
评论

相关推荐

    Go-将大型java项目转换为一个更像golang的结构

    本文将详细探讨如何将一个大型的Java项目转换为更符合Go语言习惯的结构。 首先,我们需要理解Java和Go语言的主要差异。Java以其强类型和丰富的库闻名,适合大型复杂系统的构建。而Go语言设计时注重简洁,拥有轻量级...

    go入门到精通(java转go)

    《Go语言从入门到精通(Java程序员转型指南)》 对于熟悉Java的开发者来说,学习Go语言是一项新的挑战,但也是一次技术升级的机会。Go语言,由Google开发,以其简洁的语法、高效的性能以及强大的并发处理能力,在...

    从Java到Golang快速入门

    Golang,又称Go语言,自2009年发布以来,已经发展成为一个成熟且受欢迎的编程语言,它在开发后台服务方面表现突出,很多著名项目如Docker、etcd和Kubernetes都采用它进行开发。Golang的性能可与C语言媲美,同时开发...

    ( Go for Java programmers(面向java开发者的go编程) 中文

    ### 面向Java开发者的Go编程:详细解析 #### 一、引言 ...Java开发者在学习Go语言时,需要特别注意这些概念上的区别,以便更好地理解和应用这门语言。希望本文能够帮助Java开发者顺利过渡到Go语言的世界。

    JAVA与GO语言实现的RSA加密算法的互通

    关键:(1)Java支持NoPadding填充方式,并且已经封装好相应的接口,可通过Cipher.getInstance来指定RSA/ECB/NoPadding该对齐和填充方式; (2)Golang中不支持NoPadding的填充方式,需要自己处理;

    从Java到Golang快速入门.pdf

    标题《从Java到Golang快速入门》和描述表明本文档旨在帮助Java程序员快速了解并入门Golang(通常称为Go语言)。Golang自2009年发布以来,经历了多个版本的演进,并逐渐成熟。Go语言因其性能可媲美C语言,开发效率...

    国密加密 sm4 sm2 java python golang

    国密加密解密 sm4 sm2 的java python golang实现,java和python,golang的有一定区别,需要修改点东西才可以实现。 SM4Key = ran_str = ''.join(random.sample(string.ascii_letters + string.digits, 16)) ...

    Jni-Golang:java调用golang(通过Go1.5共享库)

    1. **编写 Golang 代码**:首先,在 Go 代码中使用 cgo 定义 C 函数,这些函数将作为 Java 与 Golang 交互的接口。确保这些函数遵循 C ABI(应用程序二进制接口),因为 JNI 需要与 C 函数兼容。 ```go package ...

    自己动手写Java虚拟机(GO语言)

    《自己动手写Java虚拟机(GO语言)》是一本面向技术爱好者和程序员的书籍,它指导读者使用Go语言实现一个Java虚拟机(JVM)。这本书的编写基于《深入理解Java虚拟机》第二版以及相关的Java规范,旨在帮助读者深入...

    Goby java API工程

    首先,Goby Java API可能会包含一个或多个主要的接口,这些接口定义了与Goby系统交互的基本操作,比如初始化连接、发送请求、接收响应等。开发者可以通过实现这些接口来定制特定的逻辑,或者直接使用API提供的默认...

    java go RSA互相加解密

    java go RSA互相加解密 go rsa加密后可以用 java解密, java rsa加密后 可以用解密, 要把 txt文件中的秘钥和私钥 都复制粘贴到java 文件和go 文件 ,公钥和私钥统一才可以

    从Java到Golang快速入门.rar

    《从Java到Golang快速入门》是一份专为程序员设计的指南,旨在帮助熟悉Java的开发者迅速掌握Golang这一新兴的、高效的编程语言。本文将深入探讨Java与Golang之间的异同,以及如何利用已有的Java知识来加速Golang的...

    golang与java间的json-rpc跨语言调用需要的jar

    本话题聚焦于Golang(Go语言)与Java之间的JSON-RPC(JSON Remote Procedure Call)通信,这是一种轻量级的远程调用协议,通过JSON(JavaScript Object Notation)作为数据交换格式来实现。在这个场景下,我们主要...

    Cobol移植至Java解决方案

    - **go to**: 在Cobol中,`go to`语句用于控制流程,但在Java中,应使用更面向对象的控制结构,如`if`语句和循环。 4. **控制结构转换**: - **IF Cobol IF Java if**: 这部分涉及条件语句的转换,Cobol的`IF`...

    RSA go java 相互加解密

    在“RSA Go Java 相互加解密”的场景中,Java和Go语言应用可以使用相同的公钥进行加密,然后用对应的私钥进行解密,实现跨语言的安全数据交换。下面将详细解释这个过程以及涉及的技术点。 1. **RSA算法原理**: ...

    java客户端和go服务端联调错误演示

    在IT行业中,跨语言通信是常见的任务,例如Java客户端与Go服务端的交互。本案例中,"java客户端和go服务端联调错误演示"是一个博客的配套文件,旨在通过实际示例展示错误发生的情况,并提供正确的解决方案。下面将...

    Java_go_over.rar_Go_ Go_ Go!_java go over_javaover

    _java go over_javaover”暗示了这是一个关于Java编程语言的学习资料,特别强调了“Go_ Go_ Go!”,可能表示学习的紧迫性和进度快速。标签“go _go _go!”可能是在强调学习Java时的积极进取态度,而“java_go_over”...

    java,php,GOLang,JavaScript,AES加密解密代码互通

    本主题聚焦于四种常用编程语言——Java、PHP、GOLang(Go语言)和JavaScript——之间的AES(Advanced Encryption Standard)ECB(Electronic Codebook)模式128位加密解密的互操作性。下面我们将详细探讨这些语言...

    使用 Python、Java 和 Go 三种编程语言与 MySQL 数据库进行连接的方法

    使用 Python、Java 和 Go 三种编程语言与 MySQL 数据库进行连接的方法; 使用 Python、Java 和 Go 三种编程语言与 MySQL 数据库进行连接的方法; 使用 Python、Java 和 Go 三种编程语言与 MySQL 数据库进行连接的...

    bililili后台源代码完整版80M版本go语言 github java go语言

    【标题】"bililili后台源代码完整版80M版本go语言 github java go语言" 涉及到的是一个关于视频分享平台哔哩哔哩(B站)的后台源代码,该源代码以Go语言为主,同时也包含了Java的相关部分,并且在GitHub上发布。...

Global site tag (gtag.js) - Google Analytics