Аккаунт Войти / Регистрация
Тема
Размер текста
Let's look at: Trace, Profiling, Integration Testing, Code Coverage, Mocking, Deadlock Detection in Go vs Java | Testing, Debugging and Profiling

Let's look at: Trace, Profiling, Integration Testing, Code Coverage, Mocking, Deadlock Detection in Go vs Java | Testing, Debugging and Profiling

Series: Go for Java Developers — analysis of trace, profiling and testing

In this article we will analyze tools and practices for testing, debugging and profiling in Go. For a Java developer this will make it easy to navigate in Go, and for a Go developer — to compare approaches with Java.


Trace — program execution tracking

Go has a built-in package runtime/trace for detailed program analysis. Allows tracking goroutine, syscalls and execution time.

Trace example

// Go
import (
    "os"
    "runtime/trace"
    "time"
)

func main() {
    f, _ := os.Create("trace.out")
    defer f.Close()
    trace.Start(f)
    defer trace.Stop()

    time.Sleep(time.Second) // example work
}

Java equivalent: via Flight Recorder or JVisualVM profiler

// Java (example of recording events via Flight Recorder API)
import jdk.jfr.Recording;

public class Main {
    public static void main(String[] args) throws Exception {
        try (Recording recording = new Recording()) {
            recording.start();
            Thread.sleep(1000); // example work
            recording.stop();
            recording.dump(new java.io.File("trace.jfr").toPath());
        }
    }
}
Trace is useful for deep performance analysis and identifying bottlenecks, especially with concurrency.

CPU and memory profiling

Go provides the pprof package for CPU and memory profiling. This helps optimize resource usage.

CPU profile example

// Go
import (
    "os"
    "runtime/pprof"
)

func main() {
    f, _ := os.Create("cpu.prof")
    defer f.Close()
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()

    // load
    for i := 0; i < 1000000; i++ {}
}

Java equivalent: JVisualVM profiler or Java Flight Recorder

// Java
// CPU and heap profiling via JVisualVM / Flight Recorder
// Example of profiling manually in Java is not needed, GUI is used
Tip: profile CPU and memory regularly, especially under high loads and multithreading.

Integration Testing — integration tests

Go uses the testing package for unit and integration tests. Java uses JUnit/TestNG. In Go, tests are written simply and composed via *_test.go files.

Integration test example

// Go
import "testing"

func TestIntegration(t *testing.T) {
    result := 1 + 2
    if result != 3 {
        t.Error("Expected 3")
    }
}

Java equivalent:

// Java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class MainTest {
    @Test
    void testIntegration() {
        assertEquals(3, 1 + 2);
    }
}

Code Coverage — test coverage

Go supports code coverage analysis via go test -cover. Java — via JaCoCo or built-in IDE tools.

Command example

// Go
go test -cover ./...
Tip: 80%+ coverage is important for stability and confidence in code changes.

Mocking interfaces — dependency substitution

Go allows mocking interfaces manually or via third-party libraries (gomock). Java uses Mockito or PowerMock.

Go example

// Go
type DB interface {
    Get(id int) string
}

type MockDB struct{}

func (m MockDB) Get(id int) string {
    return "mocked"
}

Java equivalent:

// Java
import static org.mockito.Mockito.*;

interface DB {
    String get(int id);
}

public class Test {
    public void test() {
        DB mockDb = mock(DB.class);
        when(mockDb.get(1)).thenReturn("mocked");
    }
}

Deadlock detection — detecting deadlocks

Go race detector (go run -race) helps identify races and deadlocks. Java — thread dump, VisualVM or built-in IDE tools.

// Go
go run -race main.go
Tip: races and deadlocks are major multithreading issues. Use built-in tools for quick detection.

Comparison table Go ↔ Java

Concept Go Java Comment
Trace runtime/trace Flight Recorder / JVisualVM Detailed execution analysis
CPU / Memory profiling pprof JVisualVM / Flight Recorder Resource usage analysis
Integration testing testing package, *_test.go JUnit / TestNG Simple test writing
Code coverage go test -cover JaCoCo / IDE Tracking coverage
Mocking interfaces manual or gomock Mockito / PowerMock Dependency substitution for tests
Deadlock detection race detector thread dump / VisualVM Identifying races and locks

Practical conclusion

  • Go has built-in tools for testing, profiling and debugging — easier to integrate into pipeline.
  • Java offers powerful third-party tools and IDE, but requires more setup.
  • Race detector and pprof — key tools for safe concurrency work.
  • Mocking and coverage are convenient for maintainable and reliable code.
  • Comparing approaches Go ↔ Java allows quick adaptation between languages and using best practices.

Оставить комментарий

Мой канал в социальных сетях
Отправляя email, вы принимаете условия политики конфиденциальности

Полезные статьи:

Go vs Java - comparison of memory models: happens-before, visibility, reorder, synchronization events, write/read barriers
Memory model is a layer between the program and the processor. Modern CPUs aggressively optimize execution: instructions may be reordered, data may be stored in core caches, and operations may be perf…
Java v25: Choosing the Right Multithreading for Any Task
Introduction The Java world is rapidly evolving, and with each version, new tools are emerging for effectively working with multithreading, collections, and asynchrony. Java 25 brings powerful feature…
Asynchrony and Reactivity in Java: CompletableFuture, Flow, and Virtual Threads
In modern Java development, there are three main approaches to asynchrony and concurrency: CompletableFuture — for single asynchronous tasks. Flow / Reactive Streams — for data flows with backpressur…

Новые статьи:

Concurrency is not about “starting many threads”. It’s about agreements between them. Imagine a restaurant kitchen: — cooks (threads / goroutines) — orders (tasks) — and the main question: how do th…
When HashMap starts killing production: the engineering story of ConcurrentHashMap
Imagine a typical production service. 32 CPU hundreds of threads configuration / session / rate limits cache tens of thousands of operations per second And somewhere inside — a regular Map. At first…
Zero Allocation in Java: what it is and why it matters
Zero Allocation — is an approach to writing code in which no unnecessary objects are created in heap memory during runtime. The main idea: fewer objects → less GC → higher stability and performance. …