One of the most used caching schemes is Least Recently Used (LRU). Caches that use this eviction strategy will remove the least recently used item when their size reaches their capacity. That means that such caches have to keep a track of the order of access of the cached items, so it would evict the correct items. Before we go too much into details about the implementation of an LRU cache, let’s first see what are the possible applications of this caching scheme.
Over the years, people involved in computer science and engineering have worked really hard on optimisations of various natures. Given that we live in a world with limited resources, humanity has always worked on ways to optimise the costs and speed literally everything. In software engineering, I would argue, the most popular approach to performance improvement is caching. While there are various applications of caching, depending on the area of software engineering, the idea behind caching is quite simple: store data that is often needed/used in fast structure/storage so it can be retrieved very fast.
You can spend quite a bit of your programming career without working with trees, or just by simply avoiding them if you don’t understand them (which is what I had been doing for a while). Now, don’t get me wrong - arrays, lists, stacks and queues are quite powerful data structures and can take you pretty far, but there is a limit to their capabilities, how you can use them and how efficient that usage can be.
Looking at any programming language you will (hopefully!) find a rich and useful standard library. I started my professional career as a software developer with Ruby, which has quite an easy-to-use and well-documented standard library with a plethora of modules and classes to use. Personally, I find the Enumerable module in Ruby with all its nice methods simply brilliant. You might be coming from a different language, but I am sure that any serious programming language out there has a set of classes, modules, methods and functions to make your life (and work) easy.
If you come from an object-oriented background, you might have tried concurrency in your favourite OO language before. Your mileage will vary, but in general OO languages are harder to work with when it comes to concurrency. This is due to their nature - they are designed to keep state in memory and require more expertise and experience to be successful with. How does Elixir stand up to other languages when it comes to concurrency?
Being new to Elixir and Phoenix, I spend quite some time in the projects’ documentation. One thing that stood out for me recently is the first sentence of Phoenix’s Plug documentation: Plug lives at the heart of Phoenix’s HTTP layer and Phoenix puts Plug front and center. So naturally, I felt compelled to take a deeper dive into Plug and understand it better. I hope the following article will help you out in understanding Plug.
Unless you’ve been living under a rock for the last couple of years, you probably know what two-factor authentication (2FA) is. It’s quite a neat trick actually - you have a password that you have to (obviously) enter correctly (first factor), but you also have to receive a second (random) code through a different medium, sometimes on a different device, that you have to enter to log in (second factor).
In a previous post, we took a look at linked lists and how we can apply them in a hypothetical use-case. In this post, we will look at two similar but powerful data structures. Modelling actions and history Think about Excel or Google docs. You know, the most ubiquitous applications for composing documents that humanity has invented. We’ve all used them in some capacity. As you might know, these apps come with various actions one can apply to a text.
Data structures and algorithms are the bread and butter of computer science. Although sometimes they appear scary to people, most of them have a simple explanation. Also, when explained well with a problem algorithms can be interesting and fun to learn and apply. This post is aimed at people that are not comfortable with linked lists, or folks that want to see and learn how to build one with Golang.
If you have ever tried writing a daemon for MacOS you have met with launchd. For those that don’t have the experience, think of it as a framework for starting, stopping and managing daemons, applications, processes, and scripts. If you have any *nix experience the word daemon should not be too alien to you. For those unfamiliar, a daemon is a program running in the background without requiring user input.
Recently, while writing a small Golang program for setting reminders I came across a small confusion that I guess most newcomers to Golang will have - how to organise a package in a way that will enable it to cleanly contain two or more binaries. This post is not aimed at experienced Golang programmers, it’s mostly aimed at beginners to understand how to compose more complex packages, beyond making the usual “one package one binary” ones.
Idempotency is an often used term in computer science. It’s meaning to some might not be known, to others it’s very well known. The explanation for idempotency on Wikipedia is: … the property of certain operations in mathematics and computer science that they can be applied multiple times without changing the result beyond the initial application. Essentially, idempotency is the mathematical way of saying “one can apply a certain operation on something many times, without changing the result of the operation after the first time the operation is applied”.
Nowadays, having an API on top of your application is considered common. I’ve often been disapointed when I’ve been expecting an API of a product I like to find none. There are powerful tools out there that allow easy API integrations, like IFTTT.com. Also, if you want to build a mobile application to work aside your product (or maybe your product is mobile-first), then an API is a must-have - there’s no way around it.
Have you ever found yourself publishing an API, either an internal or a public one? Have your ever heard from the consumers of those same APIs back? Are they happy about the functionality of your APIs and their design? You already know, there is no perfect design, but API design has to be taken very seriously. Why? Because evolving and changing APIS is hard and time consuming. Imagine you are on a team in a company, that has set off to design a company-wide API guideline and a blueprint.
REST as a concept was introduced by Roy Fielding in his doctoral thesis, named Architectural Styles and the Design of Network-based Software Architectures. 16 years later, REST as an architecture is the most widely accepted way to design and build APIs. I am sure we have all heard about it, and most of us think we are building actual RESTful APIs. But, are we? Let’s remind ourselves what REST is and then continue on something else that supplements REST, called HATEOAS.
Starting a greenfield application everyday is nearly impossible, especially in your daily job. In fact, most of us are facing (somewhat) legacy codebases on a daily basis, and regaining the context of why some feature, or line of code exists in the codebase is very important. This is where git, the distributed version control system, is invaluable. Let’s dive in and see how we can use our git history and easily navigate through it.
Recently, I have been building an API as part of my day job. Rails is a great framework to build APIs in, and it has been a joy so far. When building the responses of the API, it’s paramount to understand what HTTP statuses you should utilize, which will in return help the consumers by providing more meaningful responses. Sure, you could always have a status property in the response JSON, which will be a human-readable status code.
Object-oriented programming and design is (or, was?) a revolutionary way of thinking and designing programs. It introduced classes, objects, inheritance, polymorphism and many other ways to think about programming. As an addition, some very smart folks identified some pitfalls and patterns that occur in object-oriented programming and put them in books. That’s how we got a list of general code smells, design patterns and refactoring patterns that we can use in our everyday work.
Most of us use Git on a daily basis. We have all read a book (or part of a book) about Git, we learned how to do commits, track additions and removals, work with branches and so on. But, there’s so much more to Git than just committing your changes. In this post I am going to rant a bit about how we don’t utilise the power of our Git history, and how one can actually start doing it.