What is the difference between Java and Go
basic grammar
Golang: The encoding style and visible domain rules are strict and simple; Java: Clear and standardized hierarchical interfaces. The main manifestations are: 1.1 Variables
a、 Variable declaration and usage
b、 Variable declaration and initialization
1.2 Scope Rules
Java: The visible domain rules for methods, variables, and classes are controlled through the private, protected, and public keywords, as follows.
| scope | Current Class | Same package | Descendants category |
|---|---|---|---|
| public | √ | √ | √ |
| protected | √ | √ | √ |
| Default (without modifiers) | √ | √ | × |
| private | √ | × | × |
Golang: There is only one way to control the visible field. When the first letter of a field starts in uppercase, it means it is visible to the outside world, and when it starts in lowercase, it is only visible to members within the package.
1.3 comma OK mode
1.4 Structures, Functions, and Methods
a、 Structure declaration and usage
The most significant difference between Golang and Java is that there is no concept of "class" in Golang, and the structure that organizes data entities is called a structure in Golang. Functions can exist outside of "classes" and can be called based on structures or package names. The structures in Golang abandon polymorphic concepts such as inheritance and implementation, and combinations can be used between structures to achieve the effect of reusing methods or fields.
b、 The difference between functions and methods
In Java, all "functions" are built based on the concept of "classes", which means that only "functions" are included in "classes". Here, "functions" are called "methods"
In Golang, the most basic difference between "function" and "method" is that functions are called based on package names instead of structures, while methods are called based on structures.
1.5 Value types, reference types, and pointers
Java: There is no explicit pointer operation in Java; The 8 basic data types are value types, while arrays and objects belong to reference types.
Golang: There are explicit pointer operations in Golang, but Golang's pointers are not as complex as C and cannot perform pointer operations; All basic types belong to value types, but there are a few types that are quite special and exhibit the characteristics of reference types, namely slice, map, channel, and interface. Apart from assignment, they can all be used as reference types. Therefore, when we do this, we can directly use the variable itself without a pointer. Note: The difference between slices and arrays is whether they have a fixed length. Slices do not have a fixed length, while arrays have a fixed length. It is worth noting that in Golang, only arrays of the same length and type can be considered as "of the same type". For example, [] int and [3] int are considered as different types, which can cause compilation errors when passing parameters.
a、 Array comparison
In Java, when passing an array to a method, the internal values of the original array can be directly modified through the passed array (shallow copy). In Golang, there are two situations: when the length of the array is not limited (as a slice), the value of the original array is directly changed, and when the length of the array is limited, a complete copy is copied for modification (deep copy)
b、 Object comparison
In Golang, the function parameter is passed as a brand new copy of the original object (with its own memory address); Assigning values between Go objects is to copy the contents of the object's memory (field values, etc.) over
In Java, the function parameter passed is a copy of the original object's reference (pointing to the same memory address); The assignment between Java objects is to copy the reference of the object, because the address pointed to by the reference has changed, so the content of the object has also changed.
c、 The difference between pointers
In Java, if a reference type (object, array, etc.) is passed, its pointer is copied and passed. In Golang, it is necessary to explicitly pass a pointer to Person, otherwise only a copy of the object is passed.
object-oriented
In Golang, there is no clear OOP concept, and Go language only provides two key types: struct and interface. In Java: the encapsulation, inheritance, polymorphism features of object-oriented languages, as well as keywords such as "extends" and "implementations".
2.1 Java OOP and Golang Structure Combination
2.2 Intrusive and non-invasive interfaces
In Java, interfaces mainly exist as contracts between different components. The implementation of the contract is mandatory, and you must declare that you have indeed implemented the interface. This type of interface is called an invasive interface. The main manifestation of 'invasive' is that the implementation class needs to explicitly declare that it has implemented a certain interface. In Golang, non-invasive interfaces do not require any keyword declaration of the implementation relationship between types and interfaces. As long as a type implements all methods of the interface, then that type is the implementation type of the interface.
The advantages of Golang's non-invasive interface are simplicity, efficiency, and on-demand implementation in Go. Classes do not have the concept of inheritance, and only need to know which methods are implemented by this type and what behavior each method has. When implementing types, you only need to focus on which methods you should provide, without worrying about how detailed the interface needs to be to make it reasonable. The interface is defined by the user as needed, without the need for prior planning to reduce the introduction of packages, because referencing an external package means more coupling. The interface is defined by the user according to their own needs, and the user does not need to worry about whether other modules have defined similar interfaces. The advantages of Java's invasive interface are clear hierarchical structure and strict management of the action behavior of types
exception handling
In Java, exception handling is performed through try.. Catch.. Finally. The code that may encounter exceptions is wrapped in a try block, and the relevant exceptions are caught and processed in a catch block. Finally, the final operation (releasing resources) is executed uniformly through the finally block. In Golang, there are two ways to handle errors: OK mode and a combination of defer, panic, and recover.
Advantages: This is much simpler than Java and is a major feature of Golang's exception handling method. Disadvantage: Code redundancy, all exceptions need to pass through if err! =Using nil {} for judgment and processing cannot achieve unified capture and processing, which can easily lead to omissions.
Defer is a commonly used keyword in Golang error handling, while pannic and recover are built-in functions in Golang that are typically combined with defer for error handling. Their respective purposes are:
The function of defer is to delay the capital punishment of a certain section of code, usually used to close resources or perform necessary closing operations. Regardless of whether an error occurs, defer code segments will be executed, similar to the role of the finally code block in Java; Defer can also execute functions or anonymous functions:
It should be noted that defer uses a stack to maintain the code that needs to be executed, so the order in which defer functions are executed is opposite to the order declared by defer.
Panic is used to throw errors and create panic during system operation. When the panic() function is called during the capital punishment of a function, the normal function capital punishment process will immediately terminate, but the statements in the function that used the defer keyword to delay capital punishment will normally expand capital punishment, and then the function will return to the calling function, and cause the panic process to be executed layer by layer until all the executing functions in the goroutine are terminated. Panic is similar to the throw keyword in Java, which is used to throw errors and prevent program capital punishment. The function of recover is to capture and handle errors thrown by panic, and it needs to be used in conjunction with defer, similar to the catch code block in Java
Note: When using the recover command to handle a panic, defer must be declared before the panic, otherwise when the panic occurs, recover cannot capture it.
concurrent programming
In Java, the CPU resource allocation object is Thread, while in Go, the CPU resource allocation object is goroutine. Java Thread has a one-to-one correspondence with system threads, while goroutine is a user level thread implemented in Go and has an m: n relationship with system threads.
4.1 Basic Implementation of Java and Golang
In Java, to obtain CPU resources and execute code units asynchronously, it is necessary to package the code unit as a Runnable and create a Thread that can run the code unit, and execute the start method to start the thread.
Java applications generally use thread pools to centrally process tasks, in order to avoid the overhead caused by repeated thread creation and recycling.
In Golang, the code needs to be packaged into functions. After calling the function with the go keyword, a goroutine is created that can run code units. Once the CPU resources are ready, the corresponding code unit will be executed in the goroutine.
4.2 Differences between Java and Golang. Golang language adopts the CSP (Communicating Sequential Processes) model, with goroutines and channels as the main implementation methods. Java adopts a multi-threaded model, with Thread and Synchronization as the main implementation methods. Golang language goroutines are lightweight threads that are created and destroyed much faster than threads in Java. In Java, creating and destroying threads require significant overhead. The channel of Golang language is a mechanism for synchronous data transmission, which can easily solve communication problems between multiple programs. In Java, synchronization tools such as Semantics, CountDownLatch, etc. are needed to solve communication problems between multiple threads.
a. Java synchronized and Golang Mutex
Go Mutex: Go does not provide basic keywords like volatile like Java, but its Mutex related memory model has very similar semantics to synchronized or Java's official library Lock implementation. If goroutine A releases sync.Mutex or sync.RWMutex at time t1, and then at time t2, if any goroutine B obtains a lock, all writes made by goroutine A before time t1 are visible to B.
b、 condition variable
The similarity between Java and Golang: Generally speaking, conditional variables are derived from locks, and different conditional variables are just different waiting queues in the same lock space. Java can use synchronized code blocks to protect specific code paths, and can also use Object wait and notify/notifyall methods in synchronized code blocks to implement single conditional waiting. If multiple conditions are required, the Lock and Condition implementations provided by the official library can be used. The difference between Java and Golang: Java creates condition variables by calling the newCondition method of the Lock interface. The Go sync. Send structure requires the sync.Mutex field to work, with the suspend method being Wait and the wake-up method being Braodcast. In Go language, the notifications for conditional variables Signal() and Broadcast() are not executed under lock protection, but after Unlock().
c. CAS/Atomic Atomicity: The characteristic of one or more operations not being interrupted during CPU capital punishment known as atomicity. CAS is an optimistic locking technique. When multiple threads attempt to update the same variable using CAS simultaneously, only one thread can update the value of the variable, while the other threads fail. The failed thread is not suspended, but is informed that it has failed in this competition and can try again. Both Java and Go support CAS and atomic operations. In Java, CAS operations are supported by the volatile keyword and VarHandle (previously Unsafe before 9), and on this basis, there are numerous lock free implementations in Atomic classes and concurrent packages (such as Concurrent HashMap, AQS queues, etc.). In Golang: atomic.Value provides the foundation for CAS operations, ensuring that any type (interface {}) of Load and Store are atomic operations, on which there is an atomic package. d. Once and singleton mode sync. Once is an implementation provided by the Golang standard library that allows functions to be executed only once. It is commonly used in singleton mode, such as initializing configurations, maintaining database connections, etc. It has two features: ensuring that a certain piece of code will only be executed once during program capital punishment. If multiple goroutines execute the Once daemon code simultaneously, only one goroutine will have the chance to execute, while the other goroutines will block until the code is executed.
There are several ways to write singleton patterns in Java, mainly lazy singleton and hungry singleton. Lazy singleton: The implementation of lazy singleton does not consider thread safety issues and needs to be combined with synchronization to ensure thread safety
Hungry man style singleton: Hungry man style creates a static object for the system to use at the same time as class creation, and will not change it in the future, so it is inherently thread safe.
garbage collection
Garbage Collection (GC) is an automatic way of managing memory. Languages that support GC do not require manual memory management. The program background automatically determines whether an object is alive and reclaims its memory space, freeing developers from memory management. Because it supports more features and more flexible GC strategies, such as generation, object mobility, various parameter adjustments, and so on. However, Go only implemented one GC scheme, which is non generational, non removable, and has few parameters to adjust. It also focuses more on optimizing pause time and executing GC more frequently. Therefore, Go usually occupies less memory, but the cost is that GC performance is much worse than JVM.
5.1 Java's Garbage Collection System Java implements garbage collection functionality based on the JVM, and its system is very large, including garbage collectors (G1, CMS, Serial, ParNew, etc.), garbage collection algorithms (tag clear, tag organize, copy, generational collection), reachability algorithms (reachability analysis, reference counting), reference types, JVM memory models, and more. After multiple generations of development, Java's garbage collection mechanism is relatively complete, and Java is divided into new and old generations to store objects. Objects are usually allocated memory in the new generation, and objects that survive multiple times will be moved to the old generation. Due to the low survival rate of the new generation and the high possibility of space fragmentation, "mark copy" is usually used as the recycling algorithm, while "mark clear" or "mark sort" is usually used as the recycling algorithm for the old generation with high survival rate, compressing and organizing space.
5.2 Golang GC Characteristics
Tri color marking, concurrent marking and cleaning, non generational, non compact, write barrier
a、 Tri-colour marking
At the beginning of the program, there are three sets: black, white, and gray. Initially, all objects are white;
Starting from the root object, mark all reachable objects in gray;
Extract objects from the gray object set, mark their reference objects as gray, place them in the gray set, and mark themselves as black;
Repeat step three until the gray set is empty, meaning all reachable objects are marked;
After marking, unreachable white objects are considered garbage, and memory is iteratively cleaned to reclaim white objects;
Reset GC status;
b、 Non generational Java adopts generational recycling (dividing different generation spaces according to the length of the object's lifecycle, placing older generations for longer lifecycles and younger generations for shorter lifecycles, with different recycling algorithms and frequencies for different generations), while Golang does not divide into generations and treats them equally; c、 Non compaction does not perform memory cleaning to remove memory fragments after garbage collection; d、 In the process of concurrent tagging, if the application modifies the object graph, there may be a possibility of tag omission. Writing a barrier is to address the issue of tag omission.
Comparison of Resource Consumption
6.1 Java's JIT Strategy Compared to Golang's AOT Strategy
Java consumes more memory at runtime compared to Golang. The reason is that the Java runtime includes a complete interpreter, a JIT compile time, and a garbage collector, which significantly increases memory. Golang language is directly compiled into machine code, and the runtime only contains machine code and a garbage collector. Therefore, the running state of Golang consumes relatively less memory.
6.2 Memory Allocation and Garbage Collector
Java does indeed have a relatively high initial usage, as the JVM requires more memory for JIT. The default GC algorithm has a higher memory requirement, but this does not mean that the usage will continue to grow linearly in the future. If the goal is to start hundreds or thousands of processes with low memory requirements, then Java is really not good at it.
6.3 The concurrent coroutine model is more memory efficient than the threading model.
6.4 Reflection
Golang's reflection is simpler, resulting in higher memory consumption for the framework compared to Java programs. Mainly because Java's framework implementation heavily utilizes reflection and uses hashmap to cache information, both of which are extremely memory consuming behaviors. Golang's framework also uses reflect and map. However, Golang is oriented towards interface and value types, which makes Golang's reflection model much simpler than Java's reflection model, and the number of objects generated during the reflection process is also much smaller.
ecology
Java is an unbeatable presence in terms of ecology, mainly due to the Spring family bucket, which has brought Java to the throne. There are also many well-known frameworks for Golang language, but they are far less influential than Spring.
Go

I have tried many Go frameworks, why did I ultimately choose this one? True fragrance

Why are many companies starting to use Go language?

Tell me about your understanding of Go
Go

Go language error handling

How strong is the Kratos that ordinary people can handle?
