Introduction Logging is an essential part of any modern Java application. Logs allow us to understand the runtime behaviour of our applications. They also help us capture the context when errors occur. Without logging debugging a production issue will often be quite tricky. Throughout my career, I have found specific logging patterns more valuable than others when on-call. And some - not so much. In this blog post, I will talk about a few of them with examples....
Introduction Recently I have been hearing about observability more and more. The promise that an observable system can help us to debug and identify performance and reliability issues in a microservice architecture sounded quite good to me. Hence I decided to read up and learn more on this topic. In this blog post I will try to summarise what I have learned about observability so far.
What is Observability? Observability is a term or a concept that has its root in Physics, mainly in Control Theory....
Executable Specifications are tests that can also serve as design specifications. They enable technical and business teams to get on the same page by enabling the use of a common language (in DDD-world this is also known as Ubiquitous Language). They function as documentations for the future maintainers of the code. In this article we will see an opinionated way of writing automated tests which could also function as Executable Specifications....
Introduction In Java, threads can have States. The Thread.State enum defines the different states that a Java thread can have. This enum defines the following values -
NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED In the subsequent sections I will provide a brief overview of these states along with possible transitions between them.
States of a Java Thread NEW This is the default state a thread gets when it is first created....
Introduction The Fork/Join framework is a framework to solve a problem using a concurrent divide-and-conquer approach. They were introduced to complement the existing concurrency API. Before their introduction, the existing ExecutorService implementations were the popular choice to run asynchronous tasks, but they work best when the tasks are homogenous and independent. Running dependent tasks and combining their results using those implementations were not easy. With the introduction of the Fork/Join framework, an attempt was made to address this shortcoming....