Projects

Ping-pong: Using multiple Kafka consumers to process events

In this post, I write about ping-pong - a project that aims at simulating how messages in a live chatroom (with multiple concurrent users) may get processed, using a Kafka messaging system.

Transitioning from Heroku Free Tier to GCP + YugabyteDB

This post captures the list of steps I followed to migrate a HTTP service from a Heroku dyno to a Google Cloud Platform instance powered by YugabyteDB cluster as the database.

My First Clojure Backend Using Ring, Jetty and Compojure

In this post I discuss how I built my first web-app, RemindMe, using Clojure! The app is deployed here: https://remind.otee.dev

Making Short Links Shorter: Using NGINX + Custom Domain

In this post, I explain how to shorten the short links generated by Twirl. For example, from oteetwirl.herokuapp.com/l/L5w2 to twirl.otee.dev/l/L5w2.

How to Deploy an App Using Google Compute Engine

In this post, we explore how to deploy code to Google Compute Engine (GCE). We will deploy a toy project, which implements Google’s OAuth 2.0 framework.

Short, Unique, & Unguessable: Generating Short Links in Twirl

This is the third and final part of a three-part series on Twirl—a web app that shortens URLs on a per-user basis. Twirl is deployed on Heroku and can be accessed here: https://oteetwirl.herokuapp.com/

Search Relevance Using BM25 Algorithm

Here, I am implementing the BM25 algorithm to retrieve most relevant items out of a set of strings, given a search query. This is the first part of implementing a bare-bones version of ElasticSearch which also uses the BM25 algorithm internally.

Twirl: User Management

This post is the first part of a three-part series on Twirl—a web app that shortens URLs on a per-user basis. Twirl is deployed on Heroku and can be accessed here: https://oteetwirl.herokuapp.com/

Diwali Hack Week

During this Diwali week, I am starting a new project and I intend to spend around 8 hours a day, hoping to finish this project within the week.

Cardimom: Using Heroku Scheduler to Initiate Triggers

In this post, I discuss how I used an external scheduler to run the Cardimom application, in order to prevent usage of Heroku’s dynos unnecessarily.

Cardimom: A Twitter Bot

This post is about Cardimom, a Twitter Bot that tweets interesting posts related to JavaScript and TypeScript!

Crisp: A Simple Lisp Interpreter

In this post, I discuss about building a simple Lisp interpreter, written in JavaScript, supporting basic Clojure syntax.

Conceptual

Understanding: Log-Structured Merge Trees

In this post, I am listing down my understanding of Log-Structured Merge Trees (LSM Trees, in short), based on my reading of the first part of Chapter 3 of ‘Designing Data-Intensive Applications’ by Martin Kleppmann.

Understanding Tail Recursion

In this post, I try to explain how tail call optimization can be used to make recursive functions (of certain kind) more efficient.

Preventing Phantom Meetings Using Transactions and Serializable Isolation

In this post, I discuss how time-slot collisions in a meeting scheduling application can be resolved. First, I discuss the business logic of determining a ‘time-slot conflict’. Second, I explain why we need transactions to prevent scheduling of concurrent conflicting meetings. Finally, I do a deep-dive on the different levels of isolation provided by database systems, to better understand why simply using transactions (with their default set-up) does not guarantee against conflicting meetings.

Kicking Around Packets: Understanding How the Internet Works

In this post, I try to answer the question “What is the internet and how does it really work?”

Who Moved My Cheese: Laziness in Clojure

In this post, I try to understand what lazy sequences are and how to create our own lazy sequence in Clojure.

For Your Eyes Only: Authentication using OAuth 2.0

How can we allow third-party apps to read our inbox without allowing them to send DMs on our behalf? How do we log-in using Google? What is OAuth and how does it work? These are some of the questions I will tackle in this post.

Reliability, Scalability and Maintainability

In this post, I am listing down my brief notes on Chapter 1 of ‘Designing Data-Intensive Applications’ by Martin Kleppmann.

Defence Against the Dark Arts: How to Store Passwords Securely

This post is all about storing passwords. What is the point of securely storing passwords? What is the difference between encryption and hashing? How are passwords stored in Twirl, the per-user URL shortening app I built using NodeJs and Express framework?

Event and Processing Time Semantics in Blog Aggregators

One of the identified limitations of the Cardimom Twitter Bot was that it maintained a system-wide cursor for fetching posts. This means that if the publication timestamp of a new post happens to be earlier than the timestamp when the system last published a tweet, it will ignore that new post. This post discusses how this limitation has been rectified in the project.

Hash Tables from Ground Up

This post is about key-value stores and hash tables. In the first part, it will discuss how key-value stores can be implemented using arrays and binary search trees. The second part will explore the design and implementation of hash tables and discuss the different ways of resolving collisions.

Cache Replacement

It is said that “There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.” This post will be on the first one.

Memoization by Way of Functional Programming

In this post, I explore the concept of memoization and show how it can be a useful technique when dealing with computationally intensive functions that need to be called multiple times in a program.

Creating Objects in JavaScript

In my earlier post, I briefly touched upon how objects are an unordered collection of values. In this post, I will explore the nature of objects in JavaScript, how they are created and the concept of inheritance and prototypes.

Higher Order Functions

In this post, I explore the concept of higher-order functions and discuss three common examples of higher-order functions.

Programming

Promises in JavaScript and Clojure

In this post I discuss how promises are created in JavaScript, some of the confusions I had while working with JS promises and how Clojure handles promises.

12 Things to Know About HTTP

This post all about HTTP and how the world wide web works.

Finding the Lexicographically Next Permutation

In this post, I discuss the solution to the LeetCode Problem, titled Next Permutation.

My First npm Package

In this post, I describe how to publish an npm package, based on my experience of publishing my first npm package, @otee/toolbox.

Implementing Graphs

A graph is an data structure consisting of a set of vertices, each of which are connected to one or more other vertices. In this post, I explore this data structure and implement some of its common operations.

Implementing Binary Search

In this post, I write about how I solved a LeetCode problem that required implementation of binary search in a sorted array.

Implementing Stacks

Stack is a common data structure that is often used to retrieve and insert data items in a specific order. In this post, I will implement some of the common operations involving stacks.

Implementing Linked Lists

In the previous post, I wrote about the concept of linked lists and how they are different from arrays. In this post, I write about some of the basic operations that can be carried out on a linked list.

Linked Lists and Arrays

In this post, I attempt to understand two of the simplest data structures: arrays and linked lists. But before that, I try to see what a ‘data structure’ actually means.

Valid Parenthesis

In this post, I discuss how I solved a problem on LeetCode on the correct order of Parentheses.

Palindrome

In this post, I discuss my experience of solving my very first problem on LeetCode.

Data-types in Javascript

In this post, I try to understand the broad differences between primitive data-types and objects in Javascript.

Defining functions

In this post, I explore the various ways of defining functions in Javascript. But before that, I also attempt to understand the very nature and utility of functions in a program.

Understanding const and Immutability

In the last post, I explored the keyword let and how it is different from the keyword var. In this post, I will explore the keyword const and the manner of declaring immutable objects in javascript.

Understanding var and let

The keywords var and let can both be used to declare variables. But are there any differences between the two?

Understanding Global and Local Variables

In this post, I will briefly analyse the manner and implications of declaring a variable as a local variable and a global variable.

Converting Strings to integers!

Strings and integers are two different types of data structures. But how to convert one into the other?

Personal

Recurse Center: Week Three

This post is about my third week at the Recurse Center.

Recurse Center: Week Two

This post is about my second week at the Recurse Center.

Recurse Center: Week One

A short post on my first week at the Recurse Center.

2021 Rewind: A Lawyer Becoming a Software Developer

As 2021 comes to an end, it is a good time for reflection. I began this year as a bankruptcy lawyer; I am ending the year, convinced that I want to be a back-end software developer. Here’s a short story of how this dramatic shift came to being.

First Milestone

I spent the last fortnight to complete the Basic JavaScript course on freeCodeCamp.

Preparing to take-off

Now that Linux is ready, I needed to install VS Code so that I can save the programs I write in the days to come.

Prologue

I am a lawyer with three years’ of post-qualification experience. But I want to learn how to code. Here’s why.

Others

Installing Linux

Today, I took some of the first tangible steps into the world of Computer Science: with the help of my brother, I installed Linux on my old Laptop.