💻 Programming and Technology Blog:

Channel direction and select patterns in Go vs Java | Patterns, idioms, and best practices in Go ← Related articles: Context, propagation and cancellation patterns in Go vs Java | Patterns, idioms and best practices in Go 1. Channel direction — channel directions In Go, channels can be one-way: only for sending or receiving. This helps to make function interfaces more safe and clear. For a...
Context, propagation, and cancellation patterns in Go vs Java | Patterns, idioms, and best practices of Go ← Related articles: Part 1 — Error handling and defer in Go (Concurrency and synchronization) | Patterns, idioms and best practices for Go 1. Context and its role In Go context.Context is used to pass cancellation signals and timeouts between goroutine, as well as to pass values (propagation). ...
Error handling and defer in Go (Concurrency and synchronization) | Patterns, idioms, and best practices in Go Error handling in Go is significantly different from the familiar Java approach with exceptions. Instead of try/catch, Go uses returning an error as a separate value, and `defer` helps safely release resources regardless of whether an error occurred or not. 1. Error handling idioms Error handling ...
Memory / Runtime / Allocator - Go vs Java Memory management, pointers, and profiling are fundamental aspects of efficient code. Let s consider three key concepts: slice backing array, pointer, and profiling (pprof / trace), and compare Go with Java. 1. Slice backing array A slice in Go is a lightweight structure over an array: it holds a po...
Practical patterns and optimization in Go vs Java | Concurrency part 3 ← Part 2 — Synchronization and Safety in Go In this part, we will discuss practical patterns for parallel task processing: worker pool, pipeline pattern, and result assembly schemes. These patterns help improve performance and avoid deadlocks. Worker Pool Worker Pool - Worker Pool 🤲⚙️ a lim...
Synchronization and security in Go vs Java | Concurrency part 2 ← Part 1 — Basics of Concurrency in Go for Java Developers In the second part, we will dive into synchronization and safety of concurrent code in Go. For a Java developer, it is useful to see the analogs: synchronized, ReentrantLock, CountDownLatch, atomic operations, and threading schemes. W...
Основы параллельности в Go для Java-разработчиков | Сoncurrency часть 1 Если вы Java-разработчик, привыкший к потокам и ExecutorService, Go предлагает более лёгкий и удобный подход к параллельной обработке — goroutine и каналы. В этой статье мы разберём ключевые концепции Go concurrency и сравним их с Java-аналогами. 1. Goroutine vs Thread Goroutine — это лёгкая единица...
Java under the Microscope: Stack, Heap, and GC using Code Examples Diagram - Java Memory Model - Heap / Non-Heap / Stack Heap (memory for objects) Creates objects via new. Young Generation: Eden + Survivor. Old Generation: objects that have survived several GC collections. Heap size is usually larger than Non-Heap. Young Generation Eden Survivor Old G...
Multithreading in Go and Java: types of tasks and solution patterns Multithreading is not just about "starting a million threads and letting them calculate". It is the art of efficiently using CPU and memory resources, safely processing data, and properly distributing tasks. In Go and Java, multithreading is used for different purposes: speeding up computations, w...
Go vs. Java - Comparing Memory Models - Part 2: Atomic Operations, Preemption, Defer/Finally, Context, Escape Analysis, GC, False Sharing Atomic operations Atomic operations ensure correct execution of variable operations without race conditions, guaranteeing a happens-before between reads and writes. Go example: import "sync/atomic" var counter int32 func increment() { atomic.AddInt32(&counter, 1) // atomic increment } Java examp...
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 performed speculatively. Without strict rules, two threads could see completely different values of the ...
How to keep a legacy project from dying and give it another 10 years Signs of a legacy project: how to recognize an old ship A legacy is not just old code. It is a living organism that has survived dozens of changes, team shifts, outdated technologies, and numerous temporary workarounds. It relies on the enthusiasm of engineers, the magical knowledge of "veterans," a...
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 backpressure. Virtual Threads / Loom — for scalable, lock-free concurrency. Figurative Understanding Flow i...
Asynchrony in Java: Future, CompletableFuture, and Structured Concurrency Java was originally designed for multithreading and parallel computing. Over time, various methods for working with the results of asynchronous tasks have emerged—from the classic Future to modern Structured Concurrency. Let s look at the main mechanisms, their pros and cons, and when to use them. 1...
Understanding multithreading in Java through collections and atomics Understanding Multithreading in Java through Collections and Atomics 1️⃣ HashMap / TreeMap / TreeSet (not thread-safe) HashMap: Structure: array of buckets + linked lists / trees (for collisions). Under the hood: on put/remove, the array of buckets is modified and, possibly, the chains are reorder...
From the microservice revolution to the age of efficiency The period from 2010 to 2020 can be called an era of separation and scaling. Systems have become too large to remain monoliths. The solution has been microservices — small autonomous applications that are deployed independently. They allowed teams to work in parallel and systems to scale horizontall...
Is it possible to know everything? The limits of mastery in a world of endless technologies Reflection on why the completeness of knowledge is unattainable and how to build a personal architecture of professional growth. Every developer has at least once thought: “How to keep up with everything?” Technologies grow faster than the list of books in bookmarks. This is not a failure — it ...
Modern architectural approaches: from monolith to event-driven systems Introduction Architecture is more than just a way to arrange classes and modules. It is the language a system uses to communicate time. Today, Java developers live in a world where the boundaries between services, data flows, and events are becoming increasingly thin. "A good architecture doesn t...
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 features to developers: Virtual Threads, Structured Concurrency, Record Patterns, and improved memory and n...
Evolution of Java language v1–v25: key features Legend ✅ — Production (can be used in production) ⚠️ — Preview / Incubator (experimental, not for production, version when it became Production is indicated in parentheses) Version Table Version Main Innovations Comment / Value Super Solution (%) Java 1.0 (1996) - Basic syntax...
By sending an email, you agree to the terms of the privacy policy

Useful Articles:

Memory, Runtime, and Allocator: A Comparison of Go and Java for Developers
In this article, we will examine the key aspects of memory management, runtime, and object allocation mechanisms in Go and Java. We will focus on the differences in approaches to memory management, wo...
Reflection on why the completeness of knowledge is unattainable and how to build a personal architecture of professional growth. Every developer has at least once thought: “How to keep up with ev...
Map internals from random order to bucket evacuation | Go ↔ Java
In this article, we will examine the internal structure of maps / hash tables in Go and Java. If you are a Java developer used to HashMap, you will be interested in how differently Go thinks. If you a...

New Articles:

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. ...
Stream vs For in Java: how to write the fastest code possible
In Java, performance is often determined not by the "beauty of the code," but by how it interacts with memory, the JIT compiler, and CPU cache. Let s analyze why the usual for is often faster than Str...
Compiler, Build, and Tooling in Go and Java: how assembly, initialization, analysis, and diagnostics are organized in two ecosystems
This article is dedicated to a general overview of how the compiler, build, and tooling practices are arranged in Go, and how to better understand them through comparison with Java. We will not delve ...