Over the last 11 years, I have enjoyed and built-up my expertise in software development working with Java technologies. In late 2016, I started on a new project on Golang, being completely new to Golang, my job quickly evolved in to a mix of both learning and implementing this new language, soon we realized that we are writing ugly and complex code because we tend to think like a Java developer while developing in Go. Soon, we came together and figured out that, we need to stop thinking like Java developer while developing in Go. So, we decided to embrace the language by developing in the most possible Go way and started having fun with it, and our code became much simpler after that.
Go is relatively easy to learn (the entire language specification fits in few pages), but there are not lot of material specifically for developers accustomed to thinking in Java.
I thought about writing this blog post to help Java developers to quickly learn and build using Golang.
Go, also known as Golang, is a programming language invented by three engineers working with Google. Initial release of Go was in 2012, born out of belief that C++ has grown too complex and feature based, Go was initially intended to appeal system-level programming. However soon it picked-up for the web development (REST) as it contains best of both worlds. It offers a light and expressive syntax, comparable to high level languages, adds static typing, powerful concurrency, and support & row performance to compatible to a low-level language.
Java is a fantastic and powerful general-purpose programming language originally developed by James Gosling with his colleagues at Sun Microsystems during the early 1990s. Initial release of Java was in 1995 with the tag line write once, run anywhere. According to Oracle, the company that owns Java, Java runs on 3 billion devices worldwide, which make Java one of the most popular programing language. It is object-oriented, has a larger community - thus library, and relies on the Java virtual machine (JVM). Avaiability of large community makes it, best fit for Large-scale, Large-team enterprise projects.

Common Between Go & Java

C Family languages
Go and Java both are C-family languages which means they share a similar language syntax. As a result, a Java developer often find reading Go code easy and vice versa.
Statically Typed
Go and Java both are statically typed, type of a variable is known at compile-time.
Garbage Collector
Go supports automatic memory management, such as automatic memory allocation and automatic garbage collection, which avoids many lurking bugs.
Memory Safe
Both are Memory Safe (Nil Reference, Runtime bound checks)
Cross Platform
Go Compiles the code into a binary file for any given platform whereas Java needs the Java Virtual Machine (JVM) to interpret compiled code.
Reflection
Java reflection convenient, popular, and commonly used whereas Go has more complex and less used.

Areas Go Differs From Java

Opinionated Language (Formatting rules)
Go enforces rules that are recommendations in other languages, for example banning cyclic dependencies, unused variables or imports, and implicit type conversions.
Error Handling
In Go it is idiomatic to communicate errors via an explicit, separate return value. This contrasts with the exceptions used in languages like Java
Built-in Concurrency
Do not communicate by sharing memory; instead, share memory by communication
Compilation
Go program compile to machine code whereas Java code compiles into bytecode which needs JVM to execute.
Control over memory layout
The Go compiler uses a process called escape analysis to find objects whose lifetime is known at compile-time and allocates them on the stack rather than in garbage-collected heap memory.
Statically Linked binaries
The Go toolchain produces statically linked Go executables by default, as long as there are no dependencies on packages using cgo, like net or os/user from the Go standard library. Statically linked application binaries have their merits; they are self-contained, and they do not have dependencies on the systems they are deployed to.
Multiple value Return Functions
Golang can return multiple values, which is a helpful feature in many practical scenarios.
Function values and Lexical Closures
Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is bound to the variables.
Build-in Strings (UTF-8)
The contents (underlying bytes sequence) of string values are immutable. The lengths of string values also cannot be modified separately.
Built-in Maps and Arrays / Slices
Strictly speaking there are three kinds of first-class citizen container types in Go, array, slice, and map.

Go Intentionally Leaves Out

Go leaves out these features as Clarity is critical when reading code, it should be clear what the program will do. When writing code, it should be clear how to make the program what you want.
No Inheritance
Coming from object-oriented background a lot of us are used to inheritance, something that is not supported by GO. Instead we need to start thinking in terms of composition (or embedding) and Interfaces. This is a very powerful way to build a data structure, but it become even more interesting when we start thinking about it in the context of interfaces.
No User-defined Generics
Go was intended as a language for writing server programs that would be easy to maintain over time. The design concentrated on things like scalability, readability, and concurrency. Polymorphic programming did not seem essential to the language's goals at the time, and so user defined generics was left out for simplicity.

Language Basics

Package
Good package names make code better. A package's name provides context for its contents, making it easier for clients to understand what the package is for and how to use it. package main This tells the Go compiler that the package should compile as an executable program instead of a shared library. The main function in this package will be the entry point of our executable program.
Imports
When you import packages, the Go compiler will look on the locations specified by the environment variable GOROOT and GOPATH. Packages from the standard library are available in the GOROOT location. The packages that are created by yourself, and third-party packages which you have imported, are available in the GOPATH location.
Access Levels
All identifiers defined within a package are visible throughout that package.
When importing a package, you can access only its exported identifiers.
An identifier is exported if it begins with a capital letter.
Exported and un-exported identifiers are used to describe the public interface of a package and to guard against certain programming errors.
Variables
A variable is nothing, but a name given to a storage area that the programs can manipulate. Each variable in Go has a specific type, which determines the size and layout of the variable's memory, the range of values that can be stored within that memory, and the set of operations that can be applied to the variable. Unlike Java each variable is initialized with default values (Zero / nil / false).
Constants
Constants are declared like a variable, but with a const keyword. Go supports constants of character, string, Boolean, and numeric values.
Functions
A function can take zero or more typed arguments. The type comes after the variable name. functions can be defined to return any number of values that are always typed.
Simple Types
Unlike any other language, Go supports some basic types like int, bool, string, float etc.
Custom Types
Go allows us to define a new custom type as struct or an interface. A struct is a collection of fields / properties. we do not need to define getter and setters on the struct fields they can be accessed automatically.
Control Structure
Unlike any other language, Go supports control flow statements, but they are limited to if else, switch, and for loop. If statements are very similar to Java except () are gone and the {} are required.
Go has only one looping construct, the for loop which is very similar to Java except () are gone and the {} are required.
Unlike any other language Switch statement in Go allows developer to avoid complex and ugly series of if else statements.
Interfaces
An interface type is defined by a set of functions. A value of interface can hold any value that implements those functions.
A type implements an interface by implementing its functions
There is no explicit declaration of intent
Implicit interfaces decouple implementation packages from packages that define the interfaces.
Supports struct typing and not duck typing.
Goroutine
Lightweight thread unlike Java
They run on top of processer thread and scheduling is taken care by Go runtime
Goroutine are asynchronous in nature
Any function in the Golang can become Goroutine by adding a keyword go before calling function, no additional implementation needed.
Channels
Default - Can hold only one value
Buffered - Can hold multiple value up to buffer size
Blocking channel - Once value is written on channel someone must retrieve/read this, before writing another value and vice versa.
Select - Select allows us to unblock a program from blocking channel by adding a default statement. We can listen on multiple channels and select statement gets executed as soon as we receive a result from one of the channels.
Closed - A channel can be closed, a closed channel does not allow us to write any value, it throws a panic, if someone tries to write on closed channel.
Direction - We can define channel direction (Read / Write) in the function parameter to avoid any misuse.
Pointers
Go has pointers but no pointer arithmetic. Struct fields can be accessed through a struct pointer. The indirection though the pointer is transparent, you can directly call fields and functions on a pointer.
Type Conversion
Go assignments between items of different types requires an explicit conversion which means that we need to convert types manually. If we are passing a variable to function expecting another type.

Final Thought

Working at Golang has clearly shown me that, there are clear distinction between two (Java and Go) and the choice between one and other is easy to do. Golang is fast, robust, and easy to understand, has native concurrency make it perfect choice for small applications and microservices that requires instense uses. However, Java requires a fair amount of over-head to spin-up and deploy a new application, its verbose nature can make it poor fit for small projects or one of utility tasks. Therefore, many Java developers keeps one or more secondary language in their back pocket, to easily complete side tasks.
Embrace Language Philosophy for Simpler Codebase
Language Basics