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.

🌐 in English
Всего лайков:0

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

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

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

Понимаем многопоточность в Java через коллекции и атомики
1️⃣ HashMap / TreeMap / TreeSet (не потокобезопасные) HashMap: Структура: массив бакетов + связные списки / деревья (для коллизий). Под капотом: при put/remove происходит модификация массива бакетов ...
Основы параллельности в Go для Java-разработчиков | Сoncurrency часть 1
Если вы Java-разработчик, привыкший к потокам и ExecutorService, Go предлагает более лёгкий и удобный подход к параллельной обработке — goroutine и каналы. В этой статье мы разберём ключевые концепции...
Error handling и defer в Go (Параллельность и синхронизация) | Паттерны, идиомы и лучшие практики Go
Обработка ошибок в Go сильно отличается от привычного Java-подхода с исключениями. Вместо try/catch Go использует возврат ошибки как отдельного значения, а `defer` помогает безопасно освобождать ресур...

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

Конкурентность — это не про «запустить много потоков». Это про договорённости между ними. Представь кухню ресторана: — повара (потоки / горутины) — заказы (задачи) — и главный вопрос: как они коорди...
История начинается не с академической теории, а с типичной production-проблемы. Представьте сервис: 48 CPU 300+ потоков нагрузка 200k операций в секунду много shared state Команда использует обы...
Когда HashMap начинает убивать продакшн: инженерная история ConcurrentHashMap
Представьте обычный продакшн-сервис. 32 CPU сотни потоков кэш конфигурации / сессий / rate limits десятки тысяч операций в секунду И где-то внутри — обычный Map. Сначала всё выглядит безобидно. Map&...
Fullscreen image