Andrea Bergia's Website| Andrea Bergia's Website
I have been using the Pest parser generator library for Rust recently in a couple of projects, and I want to talk a bit about a couple of things that weren’t too obvious for me. Pest has really good documentation in my opinion, so I won’t give you a basic tutorial. But, in the interest of making this post understandable even if you don’t know much about it, here’s an example grammar written with Pest:| Andrea Bergia's Website
Hello, and welcome to a new issue of Links list! Here are some interesting links I’ve collected recently. Bot or not? Link to heading An interesting collection of techniques used to detect whether an HTTP request comes from a browser or from a bot. There’s a ton of subtle tricks used!| Andrea Bergia's Website
I have been using IntelliJ Idea at work for a decade or so by now, and it’s been a reliable companion. JetBrains IDEs have a bit of a reputation for being slow, but their feature set is incredible: powerful refactoring tools, a great VCS UI (though I like magit even more!), a huge number of supported frameworks, integration with just about any testing library for any language, code coverage tools, powerful debuggers, etc.| Andrea Bergia's Website
Hello, and welcome to a new issue of Links list! It’s been a while, so there are a lot of links this time! Hope you enjoy the selection. Pipelining operators Link to heading An interesting article about the beauty of pipelining, in multiple languages.| Andrea Bergia's Website
Spoiler: this is a rant. 😂 I have tried to write a small side project in modern C++ recently. I wanted to have a proper setup with modern tooling and practices, in part because I wanted to see what the state of the art was for C++. So I settled on these tools: compiler: clang; build system: cmake; dependencies resolution: conan; unit test framework: I have adopted catch 2, because it looked quite simple; lsp: I have used clangd; linter: there seem to be multiple valid choices, but I have s...| Andrea Bergia's Website
In this post, I am following up on the explanation of my simple JIT compiler glorified calculator Emjay and I will show you how I implemented function calls. Why the complexity? Link to heading Imagine we are JIT-compiling the following program:| Andrea Bergia's Website
Today I wanna show off my most recent little project, called emjay. It’s a very simple “language”, with an evaluator that generates JIT code and executes it. It does not have a “normal” interpreter, only the JIT compiler. The language is extremely limited, but that was intentional, since I wanted something simple that I could write end-to-end. All the code is written in Rust and it is hosted on GitHub at https://github.com/andreabergia/emjay. It’s roughly 4k lines of code includin...| Andrea Bergia's Website
Hello, and welcome to a new post of Links lists! Hope you enjoy today’s selection. 🙂 Mistakes engineers make in large established codebases Link to heading An interesting article about working in large, legacy codebases - something I have been doing for a living most of my career. All the article is very relatable for me. I especially love this quote:| Andrea Bergia's Website
Welcome to a new post in my miniseries about some crazy bugs I’ve had to investigate and debug throughout my career. Quota Link to heading This story is from about three years ago, at a previous job. I was involved in doing a lift-and-shift migration from on-prem to Google Cloud of a bespoke system we had built for a large insurance company.| Andrea Bergia's Website
Welcome to the second post of my new miniseries about some of the craziest bugs I’ve had to investigate and debug throughout my career. Macros Link to heading This is another story that happened to me when working on a massive C++ code base, around a decade ago.| Andrea Bergia's Website
Hello, and welcome to a new issue of my Links lists! I hope you will enjoy today’s selection. Code Link to heading Doing the basic things right Link to heading A useful post on the importance of doing the basic things of a software project right. The list includes: having an up-to-date readme; have some devs’ and users’ docs; at all times, the main branch should have all tests passing; there should be a single command for building and testing; zero tolerance for flaky tests. Speaking fr...| Andrea Bergia's Website
Welcome to the first post of my new miniseries, where I’ll be sharing some of the most intricate and entertaining bug investigations I’ve done throughout my career. I hope you find these stories enjoyable! Recursion Over a decade ago, I used to work in a large and crazy C++ code base. The system had a feature that allowed our customers to search for a record based on a referred field’s value.| andreabergia.com
Hello, and welcome to a new post of Links lists! I hope you will find today’s links interesting. How large is your website? Unsurprisingly, it turns out that many websites are stupidly bloated and large. This is thanks to the ridiculous amount of advertisement, tracking, and all other bullshit that we need to endure in exchange for having tons of content for free. If only the content you pay for didn’t have these sorts of things…| andreabergia.com
In this post, I want to explain the technologies I use for building this blog. There are never enough technical blogs around, so hopefully it will inspire you to start on your own. ☺️ The website The first decision I made, a long time ago, was that I wanted to write Markdown and not raw HTML (or any sort of non plain-text format). Markdown is fast to write and edit, has enough formatting tools for my purposes, and makes it easy to compare revisions of files. I initially started writing th...| Andrea Bergia's Website
Very often, when using Spring’s dependency injection, you will simply use the @Autowired annotation on your fields, constructor or setter methods, since you know there will be one and only one instance of the required bean at runtime. However, seldom you might end up wanting to have a specific bean of a certain instance if someone has configured it in the application context, but having the possibility to use a default value otherwise. If you’re using constructor dependency injection, you...| Andrea Bergia's Website
Git has an excellent tool designed to help you reorder the commit history: interactive rebase. This can be excellent if you want to keep the history clean, so that it helps other programmers understand the logic behind the changes rather than the actual sequence of commits. Let’s walk through an example. Let’s write some history Let’s start by creating an empty project in a new directory: $ git init . Let’s create a simple program with an editor:| andreabergia.com
Hello, and welcome to a new post of Links lists! Hope you enjoy this selection. 🙂 Some tricks of modern CSS An interesting article about various stuff that can be done with one line of modern CSS. As an aside, the fact that you can actually use modern features of CSS (and JS) and expect it to work for pretty much everyone is so good. I remember the days of IE6 dominance… and I don’t miss them!| Andrea Bergia's Website
I usually write parsers by starting from a grammar and either coding a lexer/parser by hand or relying on tools such as the fantastic Antlr. However, a friend recently introduced me to parser combinators, which I found to be very interesting and useful. It’s not a recent idea, but it was new to me, and I have found it to be very interesting and useful. I have played a bit with a great Rust library called nom, and I had a lot of fun with it.| andreabergia.com
Recently, I have started working on a large code base. It can reasonably considered “legacy” in many parts, given that some of the core files that I’m touching are around 20 years old. Also, there aren’t anywhere near enough unit tests - even if there are a good numbers of integration tests. This has led me to think back to one of the best programming books I have ever read, Working effectively with legacy code by Michael Feathers.| andreabergia.com
Something that I find very important to do before undertaking big cross-team developments is to write down a design document. Unfortunately, I have seldom seen teams do that, yet they are very useful in my experience! Having design documents can really help have a good discussion about a solution, within and across teams, before you start implementing something. Furthermore, time passes. People forget the reason why a decision was taken, people leave and join teams, and having written down so...| andreabergia.com
This is the last post in my pretty long series about my toy JVM in Rust. In this post, I will do a sort of retrospective, discussing what went well and what didn’t, with Rust and with the project itself. Rust retro The good parts Sum types I have blogged about it before, but it bears repeating - Rust sum types are fantastic.| andreabergia.com
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format A JVM in Rust part 3 - Parsing class files A JVM in Rust part 4 - The Java bytecode A JVM in Rust part 5 - Executing instructions A JVM in Rust part 6 - Methods and exceptions A JVM in Rust part 7 - Objects and GC ⬅️ this post A JVM in Rust part 8 - Retrospective In this post, I discuss how I have modelled objects in RJVM - we’ll see a bit of lower-level co...| andreabergia.com
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format A JVM in Rust part 3 - Parsing class files A JVM in Rust part 4 - The Java bytecode A JVM in Rust part 5 - Executing instructions A JVM in Rust part 6 - Methods and exceptions ⬅️ this post A JVM in Rust part 7 - Objects and GC A JVM in Rust part 8 - Retrospective In this post, I will continue the discussion about how RJVM executes the Java bytecode instruct.| andreabergia.com
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format A JVM in Rust part 3 - Parsing class files A JVM in Rust part 4 - The Java bytecode A JVM in Rust part 5 - Executing instructions ⬅️ this post A JVM in Rust part 6 - Methods and exceptions A JVM in Rust part 7 - Objects and GC A JVM in Rust part 8 - Retrospective In this post, I will discuss how RJVM executes the Java bytecode.| andreabergia.com
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format A JVM in Rust part 3 - Parsing class files ⬅️ this post A JVM in Rust part 4 - The Java bytecode A JVM in Rust part 5 - Executing instructions A JVM in Rust part 6 - Methods and exceptions A JVM in Rust part 7 - Objects and GC A JVM in Rust part 8 - Retrospective In this post, I will discuss how rjvm parses .| andreabergia.com
In this post, I want to tell you about a recent project that I have been working on at my current employer, lastminute.com. We wanted to introduce a new system to replace an existing one, and we needed to do that without any downtime or losing any data. Let us discuss what we did and how! Background Our team is working on rebuilding the process that is executed whenever a flight in your reservation is delayed, changed, or canceled.| andreabergia.com
Hello, and welcome to a new edition of Links lists! It’s been a while! Tech articles How the new GitHub search works I have really enjoyed this article about how GitHub’s new code search works. The scale that GitHub handles is quite impressive - over 115 TB of code! Unsurprisingly, the new search engine is built in Rust 😊 The Technology Behind GitHub’s New Code Search | the GitHub Blog A look at what went into building the world’s largest public code search index.| andreabergia.com
This post is part of the Languages Opinion series. Languages opinion - part one - JVM Languages opinion - part two - Rust Languages opinion - part three - Javascript and Typescript ⬅️ this post Welcome back to my mini-series about programming languages. In this post, we will talk about what is probably the world’s most used programming language: JavaScript. We will also discuss TypeScript, given its relevance and usage today.| andreabergia.com
This post is part of the Future Java Releases series. Java’s evolution has sped up in the past few years, ever since the release cadence moved to a two-release-per-year model. Of course, most intermediate releases are little more than preview versions, since they are not Long Term Supported, so most people end up using either Java 8, 11, or 17. There are a lot of articles around detailing the new features in Java 11 or Java 17, so I am not going to rehearse them.| andreabergia.com
Taking notes is something pretty common, and for which there are a ton of options. I’ve tried a lot of software over the years, but my current choice is Obsidian. The main reason behind my choice is that I am a programmer and I like simple text files. Obsidian is “simply” a markdown editor, so your notes are just files on the file system that you can access with any software you want.| andreabergia.com
Today, we are talking about something that you might not know if you are new to deploying Java applications to Kubernetes. As you know, Java is a garbage-collected language. The GC in Java has a lot of parameters for tuning, and there are multiple different algorithms you can choose from, each with a particular trade-off between latency, CPU consumption, and memory overhead. One important thing to note is that each GC algorithm has some memory overhead.| andreabergia.com
PostgreSQL is a fantastic piece of software. It has been around for quite a while (since 1988!) and it has always been great, but its usage has really grown in the past decade. Not only it has long been popular in the startup scene, but I also have noticed that a lot of large enterprises are starting to abandon Oracle and moving to PostgreSQL, due to the move to cloud. And that is a good thing - Postgres is an excellent DBMS, robust and fast.| andreabergia.com
I often thought about my blog. I would find myself reading some interesting articles and thinking “oh I should link that from my blog”. But, then, laziness, work, and life won, and my blog stayed untouched. I opened the source code, and I was shocked to find I had not posted anything in almost six years. If you had asked me, I would have answered “two, three years tops”… and yet, the last post was on June 2016.| andreabergia.com
Guava contains a lot of useful methods and classes to work with primitives and do math with them; in this post we’ll briefly discuss some of them. Primitive arrays To help you work with primitives arrays, Guava includes quite a few classes: Longs, Ints, Floats, Doubles, Booleans, and others. Most of these classes contain variants of the following methods, which work on primitive types and thus avoid any autoboxing issues:| andreabergia.com
A rather common task is to model some relationship between two kinds of objects. Often you only need to go from a key to its value, and you will use a standard Map, but sometimes you will have to go back from the “value” to the “key”. In cases like this, the common solution is to build two maps: Map a2b = new HashMap<>(); Map b2a = new HashMap<>(); a2b.| andreabergia.com
Splitting strings, or building them from collections of objects, is a common task in any program. As usual, Guava has you covered with its two classes Splitter and Joiner. Splitter The Splitter class can split a String according to a character; a fixed string; a regular expression; a CharMatcher or even in pieces of the same fixed length. Creating a Splitter is quite simple: Splitter onSpace = Splitter.| andreabergia.com
We’ll cover two tiny Guava classes today, which I’m sure will provoke a “ehm… nice to know, I guess?” from you! :-) Defaults The simple Defaults class has only one method: defaultValue, which returns the “default value” given a Class: for the primitives numeric data types (char, short, int, long, float, double) it will return 0; for boolean it will return false; for byte it will return (byte)0; and for objects it will return null.| andreabergia.com
Guava contains the very powerful RateLimiter class: you’re not going to need it often, but it’s a truly useful and beautiful piece of code. This class helps you limit the rate of acquisition of a resource with respect to time, so that no more than a certain number of permits can be issued in a second. For instance you can use it to limit the number of operations done in a second, or to limit the rate of some I/O.| andreabergia.com
Imagine you have a simple class with, say, three fields, and you have to make it Comparable. You will probably write a compareTo method similar to this: public class MyTuple implements Comparable { private final int x; private final String y; private final boolean z; @Override public int compareTo(MyTuple o) { int compareX = Integer.compare(x, y); if (compareX != 0) { return compareX; } int compareY = y.compareTo(o.y); if (compareY !| andreabergia.com
The MediaType class in Guava is a useful abstraction of MIME types, also known as “media type” or “content type”. It has a lot of predefined constants for the most common types, and it allows you to create new instances specifying either a precise type or a wildcard, using “*”. Furthermore, it has the concept of “charset”, which makes it very useful when using it in web applications. Finally, it has an overridden toString method which is compliant with the RFC 2045.| andreabergia.com
Thanks to the great service offered by Let’s Encrypt, this blog now runs on HTTPS! Let’s Encrypt is a wonderful service which offers trusted certificates for free to anyone running a website. Where does this website runs? The domain was registered using NameCheap*, which I highly recommend: it’s cheap, very simple to use and very trustworthy. The whole process for registration was extremely simple and fast. The website itself runs on on DigitalOcean* cloud, which offers a service simila...| andreabergia.com
Guava contains the simple, yet very useful class Strings, with some useful methods to help you work with strings. Notable among them are: nullToEmpty: given a String, returns it if it’s not null and the empty string "" otherwise. Useful to sanitize inputs when you don’t know whether the caller will use empty strings or null. isNullOrEmpty: given a String, returns true if it is null or the empty string "".| andreabergia.com
Guava contains the tiny, yet very useful class Charsets, which has constants for all the charsets that any JVM implementation must support: UTF-8 UTF-16 in big-endian and little-endian byte orders or with the BOM (byte order mark) ASCII ISO-8859-1, also known as Latin-1. These are available as constants such as Charsets.UTF_8. This can help you avoid having to write silly code such as: try { myString.getBytes(Charset.forName("UTF-8")); } catch (UnsupportedCharsetException e) { // How can this...| andreabergia.com
The JVM will always have a value for some predefined system properties, such as java.version which represents the running JDK version, and so on. The complete list is available in the JavaDoc for System::getProperties. Guava defines an enum called StandardSystemProperty which contains an entry for each of these predefined values. All these entries have a method value which delegates to the System class. For instance you can do: assertEquals("andry", StandardSystemProperty.USER_NAME.value()); ...| andreabergia.com
Guava contains the simple and very useful class ThreadFactoryBuilder, which is most commonly used to set the thread names when using an Executor. This should always be done: thread names pop up in stack trace, when monitoring a running application with VisualVM, when printing deadlocks and so on. Doing this with ThreadFactoryBuilder is very simple: Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat("my-name-%d").build()); The threads in the pool will be named my-name-1, m...| andreabergia.com
Guava contains the very useful class Throwables, which has the very useful method getRootCause. Given an exception, this method will return the original cause by following the cause hierarchy until it finds the first exception which has no underlying cause. For example: try { throw new IOException(new IllegalArgumentException(new NumberFormatException("Foo"))); } catch (Exception e) { assertTrue(Throwables.getRootCause(e) instanceof NumberFormatException); } If the given exception has no caus...| andreabergia.com
Joda-Time is without a doubt the best way to work with dates and times in Java, unless you happen to be working exclusively on Java 8+, where you can use the new java.time library, also known as JSR 310. With Joda you can easily parse dates, times and timestamps using DateTimeFormatter. For example you can use: DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); LocalDate date = formatter.parseLocalDate("2015-12-25"); assertEquals(2015, date.getYear()); assertEquals(12, dat...| andreabergia.com
Now and then you will have an ORDER BY clause in a SELECT over a column which can have NULL values. The order where the NULL values will be placed depends on the DMBS; by default Oracle will place NULLs at the end for ascending sort and at the beginning for descending sort. However many databases (including Oracle and PostgreSQL, but excluding SQL Server, SQLite and MySQL) allow you to use the standard SQL clause NULLS FIRST or NULLS LAST to override this behavior, or for portability:| andreabergia.com
Knowing what your application is doing in production is critical for any team. Generally this is accomplished via a lot of logs; sometimes with specialized dashboards. An important tool to gather information is collecting metrics: metrics are (generally) numeric values exposing an information about the state of your application. For instance, common metrics that are tracked include the number of requests, the time elapsed for processing a request, the number of exceptions, and so on.| andreabergia.com
Guava, among its many useful things, contains a great implementation of a cache. A cache, as you know, is an object that manages an association between keys and values, like an hash map, used when the values are generally very “heavy” to calculate and you want to avoid doing that repeatedly. The main difference between a cache and a generic map is that the cache generally has some kind of “eviction” policy, i.| andreabergia.com
Maps and List are the bread and butter of any Java program, but sometimes you need to creating a map that associates one key to multiple values and end up creating a Map> or similar. If you’ve ever needed that sort of collection, Guava has you covered with its Multimap. Guava’s Multimap is designed to represent a map where for one key there is a collection of values. There are two main variants (subinterfaces) of Multimaps: ListMultimap, which acts as if the collection is a List (meaning ...| andreabergia.com
Guava is one of the most well-known Java libraries. It includes various interesting things, such as preconditions, caches, bloom filters and various collections. Today, we’re going to discuss the immutable collections found in Guava. Motivation Immutable objects are generally really good things to have in a program: being immutable means that they are automatically thread-safe (since no one can modify them, you don’t need locks!). Furthermore, since they cannot be change, they can be used...| andreabergia.com
Last time we talked about Optional in Java as a way to express the concept of “no valid value”. However, sometimes there is a better choice: we can use the Null Object Pattern. The idea behind it is simple: rather than returning null (or a missing Optional) sometimes it is possible to return an object with an “empty” implementation. This object will generally do nothing when its methods are invoked.| andreabergia.com
It’s possible to detect deadlocks programmatically in Java. This can be done via the class ThreadMXBean, by using its method findDeadlockedThreads: ThreadMXBean bean = ManagementFactory.getThreadMXBean(); long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked At this point we can iterate on the threadIds and print some information about each deadalocked thread: if (threadIds != null) { logger.error("Threads in deadlocks: {}", Arrays.toString(threadIds)...| andreabergia.com
Today I’m going to show you a few small features about enums in Java. You should know about all of this already, but in case you don’t, I hope to teach you something useful. :-) Member functions and variables Enums, that have been available since Java 5, are more powerful than first appears: they can have full fledged member functions and variables. They cannot have public constructors, since no instance can be explicitly created, but they can have private constructors.| andreabergia.com
Window functions are an extremely powerful powerful part of the SQL 2003 standard, supported by most modern releases of databases such as Oracle 8+, Postgres 9.1+, SQL Server 2005+ and others. Sadly neither SQLLite or MySql seem to support them yet, but if you are working with a database where they are available, do use them: they can make your life a lot easier. Generally, with window functions, you can write simpler and faster code than you would without.| Andrea Bergia's Website
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format A JVM in Rust part 3 - Parsing class files A JVM in Rust part 4 - The Java bytecode ⬅️ this post A JVM in Rust part 5 - Executing instructions A JVM in Rust part 6 - Methods and exceptions A JVM in Rust part 7 - Objects and GC A JVM in Rust part 8 - Retrospective In this post, I will discuss how the JVM bytecode works.| andreabergia.com
This post is part of the Writing a JVM in Rust series. I have written a JVM in Rust A JVM in Rust part 2 - The class files format ⬅️ this post A JVM in Rust part 3 - Parsing class files A JVM in Rust part 4 - The Java bytecode A JVM in Rust part 5 - Executing instructions A JVM in Rust part 6 - Methods and exceptions A JVM in Rust part 7 - Objects and GC A JVM in Rust part 8 - Retrospective In this post, I will discuss the .| andreabergia.com
Error handling is a fundamental aspect of programming. Unless you are writing “hello world”, you will need to handle errors in your code. In this post, I will discuss a bit the most common approaches used by various programming languages. Return error codes This is one of the most ancient strategies - if a function can fail, it can simply return an error code - often a negative number, or null.| andreabergia.com
This post is part of the Languages Opinion series. Welcome back to my mini-series about programming languages. In this post, we will talk about one of the most interesting programming languages that I have seen in a long while: Rust. This is gonna be a rather long post, but I have tried to stay at a pretty high level, to give you an overview of the language, its strength, and its weaknesses as I see them.| andreabergia.com
This post is part of the Languages Opinion series. In this short series of articles, I want to talk about programming languages. I love learning them, and I always try to read up a bit whenever any new language gains significant traction. In these posts, I want to focus on which programming languages I believe have had the most impact in the past decade. Note that this will be a highly opinionated piece, based on my experiences - you might have a lot of different opinions, and that’s fine!| andreabergia.com
Hello, and welcome to a new edition of Links lists! Tech articles Hexagonal architecture The “hexagonal architecture”, also called “ports and adapter”, is not particularly new. It still is a very good way of designing your applications and comes with real benefits. Here is a really good introduction to the topic. Hexagonal Architecture: Three Principles and an Implementation Example - OCTO Talks ! Documented in 2005 by Alistair Cockburn, Hexagonal Architecture is a software architectu...| andreabergia.com
This post is part of the Future Java Releases series. In this third and last post in the future of Java series, we will focus on another great new feature of the JVM, designed to improve performance. But, before talking about the language and JVM evolution, I am going to give you some background on what this enhancement plans to improve. Value classes and primitive wrappers It is pretty common, in Java and in OOP languages in general, to talk about value classes.| andreabergia.com
Today we are going to talk a bit about code design. In particular, I wanna talk about a design smell often called primitive obsession, and a related technique that can help you improve the code quality. Primitive obsession We’ll use the following Java class as the basis of the discussion: class Book { private String isbn; private String title; private int year; } ISBN is the international standard for book identifier - basically, it is a globally unique ID assigned to the book.| andreabergia.com
Hello, and welcome to a new edition of Links lists! Tech articles Upgrading version of Java at scale LinkedIn runs a lot of Java - over one thousand applications! It makes sense, though, to allow them to make use of the various GC performance improvements that have been made between Java 8 and 11 (and again in Java 17). However, updating such a large code base is bound to take some time.| andreabergia.com
This post is part of the Future Java Releases series. In this second post in the future of Java series, we will focus on a new feature of the JVM designed to improve performance. Project Loom - Virtual Threads Project Loom aims to deliver new and improved APIs and JVM enhancements for concurrency. Concurrency has famously been a hot topic for ages, since Moore’s law started to slow down a few years ago and chip makers started creating CPUs with multiple cores.| andreabergia.com
Hello, and welcome to a new edition of Links lists! A few longer but interesting articles this week, and a couple of short ones. I hope you enjoy them! Tech article Swapping memory at Meta Swapping unused memory to the disk, to fit more applications in RAM, is a simple concept that all developers (I hope!) are familiar with. This article from FacebookMeta explains how they have built an infrastructure, composed of a kernel module and a userspace agent, to more aggressively implement swapping ...| andreabergia.com
Hello, and welcome to a new edition of Links lists! Coding Kubernetes and the OOM killer A couple of links related to my latest post, on the Kubernetes OOM killer. How to Troubleshoot Kubernetes OOM and CPU Throttle – Sysdig Managing Kubernetes OOM can be a challenge. In this article, we will help you to detect common issues related to the resource usage and set fair quotas. Carlos Arilla, Sysdig How to Fix OOMKilled Kubernetes Error (Exit Code 137) | Komodor OOMKilled (exit code 137) occur...| andreabergia.com
Hello, and welcome to a new edition of Links lists! A bit more low-level stuff this week! Coding Blurring backgrounds in video chats Interesting article from Slack about how they have implemented blurring the video call background in clips. Building Background Effects for Clips - Slack Engineering Last September, Slack released Clips, allowing users to capture video, audio, and screen recordings in messages to help distributed teams connect and share their work.| andreabergia.com
As promised in a previous article, let’s discuss what MVCC is and why it is fundamenta to the workings of PostgreSQL. Even if you are a dev and not a DBA, I believe it is very helpful to have at least a rough understanding of how it works. Let us start with an example. We have a very simple schema such as: create table book ( book_id bigint, title varchar(256) ); insert into book (book_id, title) values (1, 'The lord of the rings'), (2, 'Crime and punishment'), (3, 'The moon is a harsh mist...| andreabergia.com
Hello, and welcome to a new edition of Links lists! Rust and some history this week! Coding Rust in the kernel Many people are advocating for integrating Rust in the Linux kernel, which is written (mostly) in C and assembler. Rust is famous for its memory safety guarantees, which is why many people find that it could have a place for writing kernels and drivers. In particular, Google has setup a public prototype and has an interesting post on a sample driver written in Rust.| andreabergia.com
Hello, and welcome to a new edition of Links lists! Don’t miss out on the non-coding link this week! Coding The test pyramid A very long, and well done, article about many different kinds of automated testing. Really worthwile read. The Practical Test Pyramid Find out what kinds of automated tests you should implement for your application and learn by examples what these tests could look like. Ham Vocke, martinfowler.com Low level architectures Two interesting articles about low level archi...| andreabergia.com
Hello, and welcome to a new edition of Links lists! C++, Rust, Kubernetes and careers this week! Coding Optimizing C++ std::sort at Google scale The algorithm in the STL of C++ are very powerful and very widely used. This article is a very in-depth look at how and why Google modified the implementation of std::sort. The changes have been merged in LLVM and will be available to everyone soon. Changing Std::sort at Google’s Scale and Beyond TL;DR; We are changing std::sort in LLVM’s libcxx.| andreabergia.com
Hello, and welcome to a new edition of Links lists! No strict “coding” this week, but a few interesting articles about infrastructure and networking. Infrastructure The value of simulating systems An interesting article about building simulators, for validating your hypothesis and beliefes. Not something that I have seen discussed often, or indeed thought of doing myself. But it seems like a very promising idea, worth exploring! Simple Simulations for System Builders - Marc’s Blog Even ...| andreabergia.com
I’m going to try and start a new kind of periodic post: links lists! I am going to keep track of interesting articles I find, and link to them here, hopefully once a week. It’s something I’ve seen some bloggers do, and I quite enjoy reading this sort of posts. So, without further ado, here is the first edition of my new Links List! Programming Local development Two interesting articles that propose using a real cloud environment when developing rather than locally run services, especial...| andreabergia.com
In the previous part of this series we have started writing our own gradle plugin. Let’s go on. As last time, the code can be seen at https://github.com/andreabergia/sample-gradle-plugin/tree/b7aeccc31e6285d2fbe4dab8024d1d1cbbddf698. Creating a Task class A rather common thing to do when writing a Gradle plugin is to create a class that implements the Task interface. In turn, this allows users of your plugin to create tasks of your class, which will execute a Groovy (or Java) method when th...| andreabergia.com
In this short series, we are going to dig a bit in how one writes a gradle plugin. Our plugins won’t do anything useful except some println; however I hope to manage to explain some concept and to save you some time in case you have to write one. The source code for this tutorial is available on github at https://github.com/andreabergia/sample-gradle-plugin. Our first plugin The repository is split in two projects: gradleplugin and usage.| andreabergia.com
I’ve recently discovered a “gotcha!” in the really useful standard Java class ThreadPoolExecutor. I think that this deserves a post, since it’s quite interesting and non obvious. Executors Executor and ExecutorService are really useful objects for designing multi-threaded applications in Java, and they have been introduced - alongside a lot of excellent other classes - in Java 5, as part of the java.util.concurrent package. If you don’t know about them, you should really read the ex...| andreabergia.com
In the last post we have discussed a bit how to use Dropwizard’s metrics, a great library that helps adding metrics to a Java application. In this post, we’ll see a very simple example project with a couple of metrics in it, and then we’ll expose those via JMX and monitor them via VisualVM. The code The code for this post is available on GitHub at https://github.com/andreabergia/metrics-jmx. Let’s see the simple Main class:| andreabergia.com
Optional is a new class introduced in Java 8. However, a very similar class has been available in Guava for quite some time. Optional is a generic class which should be used to represent the concept that a value might be missing. Very often methods that might return a valid object only under some conditions end up returning null in case no valid object could be built. For instance, Map::get returns null in case the key could not be found in the map.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have written the ANTLR grammar for an assembler for our virtual machine. In this part, we’ll write the code connected to the ANTLR-generated parser to actually make our assembler work! The code for this part is on GitHub. Main Let’s start - for once! - with the main function and not with an unit test.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have added support for functions calls to our virtual machine. This time, we’re going to start working on something a bit different: we’re going to write an assembler for our VM! The status of the code for this part and the next is on GitHub. Assembler? Wikipedia says: An assembler is a program which creates object code by translating combinations of mnemonics and syntax for operations and addressing mod...| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have implemented an “if” and a “while” statement. In this part, we’ll extend our virtual machine and add support for function calls! The status of the code at the time of this article can be seen on GitHub. Calling a function A function is generally nothing more than a particular address that the code jumps to.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have added many instructions to our virtual machine, such as jumps and local variables. It’s now time to discuss how we can use these instructions to implement an “if” statement, or a “while” loop. The complete unit tests implementing the code samples below can be on github. Implementing an IF Let start by implementing an if statement in our bytecode.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have implemented quite a few instructions for our virtual machine. In this part, we’ll further extend its capabilities by adding some comparison instructions, the ability to do jumps and local variables. The relevant code for this part can be seen on github. Comparison instructions Let’s add a few simple instructions to our repertoire: we’re going to add some instructions to compare two numbers.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In the previous part we have started writing some code for our stack based virtual machine. In this part, we’re going to extend the catalog of instructions that our CPU can support. The code for this article can be found on github. Arithmetics Our VM can already handle additions, so teaching it to add subtractions, multiplications and (integer) division won’t be very hard.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. After the introduction in the last part, it’s time to start writing some code and dig into stack based virtual machines. We’re going to write a very simple VM in Java (yes, that’s a stack-based virtual machine - our program - running on a stack-based virtual machine - the JVM - that runs on a register-based hardware machine - your CPU.| andreabergia.com
This post is part of the Stack Based Virtual Machines series. In this series we’re going to delve a bit into stack based virtual machines. First we’re going to see an overview, then we’ll build our own toy VM. Next, we’re going to see how what we’ll build maps to a real CPU. Finally, we’ll discuss the most famous of all: the JVM. Introduction What’s a stack based virtual machine then?| andreabergia.com
In this post, we’re going to discuss a very useful SQL extension to work with hierarchal queries. This is sadly only implemented by Oracle and although a few other databases support it as well, it won’t work in PostgreSQL, MySql nor SQL Server. The dataset Let’s create a very simple hierarchal dataset to work with. CREATE TABLE GeoArea ( parentName VARCHAR2(100), code VARCHAR2(100) ); INSERT INTO GeoArea VALUES (NULL, 'World'); INSERT INTO GeoArea VALUES ('World', 'Europe'); INSERT INTO...| andreabergia.com
Now that we’ve completed our introduction to parsing, let’s start to see how a real grammar looks like. In this post we’re going to write a grammar for about the simplest “language” I could think of: JSON. I’m going to use ANTLR v4’s syntax. ANTLR is a great tool for generating parsers from grammars, used in a lot of real world projects. From the ANTLR about page: ANTLR is a powerful parser generator that you can use to read, process, execute, or translate structured text or bin...| andreabergia.com
This post is part of the Introduction to parsing series. In this part we’ll complete our initial goal, adding the ability to our parser to calculate the symbolic derivative of an user-defined functions. We’ll also take a couple of shortcuts to keep the code focused on the parsing, and leave the improvements as “an exercise”. :-) The GitHub commits for this part are here and here. Calculating the derivative of a Node Before modifying our parser, we need to be able to calculate the deri...| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we have set up the stage for user defined functions. In this (short) part, we’ll integrate them with our parser. The relevant commit for this post is here. Adapting the grammar At the moment our parser’s grammar (excluding the expressions) looks like this: program: [end-of-line]* [statement end-of-line+]* statement: assignment | expression; assignment: variable '=' expression; The syntax we’re going to allow for o...| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we have finished adapting our parser to use our AST structure. This time, we’re going to work on supporting user-defined functions. The code changes for this part are here. Defining user functions Currently our parser supports a limited sets of pre-defined functions, implemented in C++ (although actually we have only used functions from the standard library).| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we completed our preliminary work. This time, we’re finally modify our parser to use the new tree structure we’ve built. The commit we will discuss in this post is here. The commit includes a lot of changes all at once, so we are going to go through it rather slowly. First step: adapting variables We have to modify the various methods in the parser that used to handle expressions, terms, factors and similar so that ...| andreabergia.com
This post is part of the Introduction to parsing series. In this part, as in the last one, we are going to work on the preliminary changes required to make our parser work with an AST. Variables Let us now implement a new node type which returns a variable’s value. We will use this node to implement a form of delayed variable access: the node will only store the variable’s name, rather than the variable’s value at definition.| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we started adapting our parser to work with an AST, as a step towards handling function definitions. In this part, we’ll continue on that road. More nodes type The last time we implemented a NumberNode and an AdditionNode. It’s time to implement the nodes for the other three basic operations. The tests are: CASE("SubtractionNode") { NumberNode n1(1), n2(2); SubtractionNode node(n1, n2); EXPECT("1 - 2" == node.| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we made our parser work with variables. In this part, we’ll take a step back and start setting up the infrastructure for handling function definitions. Immediate evaluation vs AST Our parser is currently working in an “immediate evaluation” mode: as soon as a token is found, it is evaluated. While this has worked well for us so far, it will cause problem when we’ll move towards letting the user define functions:...| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we have worked on some preliminary changes to our parser to handle variables. In this part, we will actually make our parser understand variables! Grammar changes and more lookahead tokens After a couple of clean-up commits, we are ready to start extending our parser. The grammar is currently this: program: [end-of-line]* [expression end-of-line+]* expression: term [ ('+'|'-') term ]*; term : factor [ ('*'|'/') factor]*...| andreabergia.com
This post is part of the Introduction to parsing series. In the last part we have taught our parser how to handle function calls. For this time variables were promised… but it turns out we have some details to handle before we can get to them. Onwards! Programs There are two issues that we need to iron out before we can successfully parse variables: one conceptually simple but long to implement, which will be the subject of this post, and one shorter but more complex that we’ll leave for ...| andreabergia.com