ESC
October 15, 2024
Unique and Exclusion Constraints in Postgres
September 14, 2024
Types From Tables in PL/pgSQL
Dynamic Commands in PL/pgSQL
September 7, 2024
Trigger Execution Order in Postgres
Inserting Data in Postgres
Statement Triggers in Postgres
August 24, 2024
Avoiding Unnecessarily Running Triggers in Postgres
May 2, 2024
Simple Semaphore With a Buffered Channel in Go
wc clone
April 28, 2024
Two Approaches To Building A Chat Server
April 13, 2024
Building My Own Git
October 31, 2022
Format Strings in Rust
August 18, 2022
Genqlient
June 15, 2022
Structural vs. Nominal Type Systems
January 16, 2022
🎙️, 🎙️ - Is this thing on?
October 15, 2021
Evaluating GCP's Cloud Key Management Service
July 29, 2021
Invert a Binary Tree
July 27, 2021
I made a dumb linux mistake
July 20, 2021
What happens when you go to this site?
July 13, 2021
Running Containers on AWS
July 9, 2021
Exploring Kubernetes Ingress
July 6, 2021
How To Revert a Merge Commit
July 5, 2021
How To Reverse a LinkedList
June 25, 2021
Everything Useful I Know About kubectl
May 10, 2021
What is a VPN?
April 15, 2021
Lua Libraries in Istio's EnvoyFilter
February 2, 2021
Pulumi vs Terraform
January 26, 2021
Notes on Jan 4th, 2021 Slack Outage
January 20, 2021
Socket Hang Ups
September 11, 2020
Consistent Hashing
September 2, 2020
Why spend innovation tokens on a service mesh?
July 13, 2020
Overlays over templating
May 26, 2020
Intro to Bigtable
March 24, 2020
Deep Dive into Joining in Kafka Streams
March 3, 2020
Sensible Schema Evolution
February 17, 2020
Landing a message from Kafka
February 10, 2020
Git home
February 3, 2020
Choosing the right scope function in Kotlin
January 27, 2020
Inline Functions
January 20, 2020
Kotlin Algorithm Challenge #3
January 16, 2020
Change Data Capture
January 13, 2020
What do data classes give you in Kotlin?
January 5, 2020
Kafka Hello World
January 2, 2020
Kotlin Algorithm Challenge #2
January 1, 2020
Kotlin's Lambda Syntax
December 19, 2019
Kotlin Algorithm Challenge #1
November 20, 2019
Exactly Once
October 16, 2019
Introduction To Celery
August 21, 2019
How the Node.js Event Loop Polls
July 26, 2019
Asynchronous I/O
July 10, 2019
Generators in JavaScript
July 8, 2019
Classes in JavaScript
June 24, 2019
Modules in Node.js
June 21, 2019
Data Structures and Database Indexes
June 14, 2019
HTTP Persistent Connections
June 3, 2019
Git's DAG
May 29, 2019
Gradle is a DAG
May 9, 2019
What is a topological ordering?
May 6, 2019
What is a DAG?
April 27, 2019
Dijkstra’s Algorithm in Kotlin
April 14, 2019
How similar is the execution of Java and JavaScript?
July 25, 2015
Introduction to Monte Carlo Methods
This article delves into two types of constraints in Postgres: unique and exclude. These two constraints are interesting because they are the ones that operate across multiple rows.
PL/pgSQL functions can reuse types of columns in tables. These can be used as return types or for declaring a variable in the function.
PL/pgSQL allows you to run dynamic commands with the `execute` keyword. This means you can do things like run a query where you don't know the table name ahead of time.
While the SQL standard specifies that multiple triggers should be fired in time-of-creation order, PostgreSQL uses name order. This article demonstrates this behavior.
There are a lot of ways to insert data into a Postgres database, including inserting with values, inserting with select, upserting, and copying data from a file.
Postgres has row-level and statement-level triggers. This article goes into the latter, with a focus on how statement-level triggers have become more useful after the introduction of "transition tables" in PostgreSQL 10.
This article highlights the use of triggers in Postgres, and how certain performance issues can arise. It also provides solutions to avoid these issues.
Buffered channels in Go can simulate semaphores for worker pools. By using a buffered channel, you can limit the number of concurrent goroutines and ensure all tasks complete using `sync.WaitGroup` to wait for all workers to finish.
wc is a command-line tool for counting characters, bytes, lines, and words in a file or from standard input. In this post, lets build our own version.
As a coding challenge, I built a chat server. We take two approaches, one involving a router, and another involving a user directory data structure.
I've been on a journery to understand more deeply git's internals. Recently, I built a toy version using TypeScript and Commander.
Rust macros like `println!` use format strings to transform values. They have their own syntax, which we'll explore in this article.
At work, we generate types from GraphQL using TypeScript for a better development experience. Seeking a similar setup in Go, I found Khan Academy’s genqlient.
Structural typing, seen in TypeScript, allows type compatibility based on structure. Nominal typing, used in languages like Java or Kotlin, requires explicit type names.
In the past few months, I've had one of the most interesting challenges of my engineering career. I lost the ability to control a computer with my hands.
Cloud KMS is a tool provided by GCP that can help for storing sensitive data like passwords or API keys.
In an inverted binary tree, each node is swapped with its corresponding node on the opposite side, akin to rotating the tree around its center axis.
ls -lh shows the disk space used for directory metadata, not the actual file sizes within directories. This can make you think you're dealing with less data than you actually are.
If you go to the browser, and type in a domain name, what happens next? In this post we'll explore the infrastructure involved in a DNS query.
Since I have far more experience with Kubernetes, I wanted to explore what running containers would look like on AWS, especially not using EKS.
At my last job, we had an outage of our ingress controller, Kong. In order to debug this, we had to go deeper than I had previously gone into Kubernetes ingress controllers.
If you merged a PR and you want to undo it, you can revert the merge commit - given you use merge commits.
To reverse a linked list in O(n) time complexity and O(1) space complexity, you need to carefully manage the pointers. Here is a Python implementation along with a walk-through of the algorithm.
This article provides a comprehensive guide to using kubectl for managing Kubernetes resources. It emphasizes minimizing the use of imperative commands in favor of declarative configuration through the apply command.
The article explains the basic concept of VPNs, highlighting their ability to provide access to private networks and hide locations through encryption and encapsulation.
Here we discuss running an Envoy plugin within an Istio sidecar. The solution involves using Istio's EnvoyFilter to run Lua scripts for outgoing requests and the userVolume annotation to inject the library into the sidecar.
Pulumi and Terraform are the two leading Infrastructure as Code tools. We compare the two, looking at their strengths and weaknesses.
The root cause analysis of Slack's January 4th, 2021 outage highlights the complexity of resolving such incidents, often involving multiple interrelated issues rather than a single root cause.
At work, we encountered socket hang up issues after implementing connection pooling between two microservices, A and B. The problem was due to mismatched timeouts.
Consistent hashing ensures even traffic distribution in load balancing. This method allows adding or removing servers without re-indexing existing traffic, maintaining stable performance.
A service mesh, such as Istio, enhances observability, security, and traffic management in a K8s cluster. Key benefits include detailed metrics, mTLS for secure traffic, and advanced routing.
Kustomize offers an alternative to templating for managing Kubernetes manifests by using overlays to create variants of base configurations. This is cleaner than Helm.
Studying for the GCP Architect exam revealed the complexities of Cloud Bigtable, a NoSQL wide column store database, originally detailed in Google's Bigtable paper.
Joining in Kafka Streams is complex due to the involvement of time and the need for proper key and partition alignment. Key concepts include the stream-table duality, windowing, and different join types (inner, left, outer).
Lately I've been thinking a lot about best practices of evolving schemas in with Kafka, something that is often overlooked—this article is the result of all of that.
This article explores how an Avro-formatted message is transformed from binary data in a Kafka topic to a strongly typed object in a consumer application.
This post goes over a git alias I use almost every day. The alias resets the working tree, cleans it, checks out a branch, and pulls the latest changes.
For newcomers to Kotlin, the scope functions can be hard to wrap your head around. With similar sounding names (`let`, `run`, `apply`, `also`, `with`), choosing the right one can be difficult.
Inline functions are a powerful feature in Kotlin. They can increase performance, allow non-local returns, and provide reified type parameters.
This article goes over the Reverse Integer problem on LeetCode. The problem is to reverse the digits of a 32-bit signed integer.
Change data capture (CDC) is a method that makes data changes available across a system, which is especially useful in microservices architectures to avoid direct database sharing.
Data classes are a well-known feature in Kotlin. They're appropriately named, since it’s designed for classes that hold data—that’s where the main value of this feature come into play.
Apache Kafka is one of the most groundbreaking technologies we software developers get to work with these days. It’s used for streaming applications, as well as for piping data all throughout a system.
This article goes over the Longest Substring problem on LeetCode. We want to, given a string, find the length of the longest substring without repeating characters.
The article provides an introduction to lambda functions in Kotlin, highlighting their benefits and syntax. Lambda functions are small, anonymous chunks of code that can be passed around.
This article goes over the Add Two Numbers problem on LeetCode. We want to, given two non-empty linked lists representing two non-negative integers, add the two numbers and return it as a linked list.
In Kafka, exactly once delivery ensures a message is written exactly once to a topic, achieved through idempotent producers and `acks=all` settings. Here we go over how it does that.
Celery is a distributed task queue, which means it spreads work across a bunch of threads and machines. If you go through the work of defining tasks, you have a scalable entity (the workers) that you can use as a knob to scale with volume.
Node.js’s event loop is implemented in a library called libuv, which is also used by Julia and Python. We’re going to dive into its internals.
Node.js optimizes performance by using non-blocking I/O, avoiding maintaining multiple threads for concurrent operations. This can be beneficial, because there is overhead in creating and maintaining threads.
This article goes over JavaScript generators, which are functions that can pause and resume execution. They can be used to create iterators.
Classes in JavaScript are a construction from ES6. There are subtleties in them that you dont find in other languages, because JavaScript is not like other languages—it does prototypal inheritance.
When programming in Node.js, it's important to understand the basics of the module system, such as scope, exports, and how that allows you to do some caching.
A database index is an extra data structure in a storage engine with the goal of faster retrieval. It’s not the primary storing entity for the data, and it has to be maintained on writes.
Sockets are endpoints of connections used in TCP. When navigating to a website, the browser establishes a TCP connection, sends an HTTP request, and typically closes the connection.
Commit objects in Git contain information about revisions, pointers to parent commits, and metadata, forming a structure where branches are pointers to commits and the HEAD ref points to the current branch.
Gradle, a build tool, uses directed acyclic graphs (DAGs) to manage task dependencies, ensuring tasks like compileJava are completed before dependent tasks like build.
A topological ordering of a directed graph is an ordering that satisfies the graphs dependencies. These are commonly used in build systems like Gradle.
A directed acyclic graph is one of the most important data structures we deal with in software engineering. You can't understand Git without grasping the main concepts of this data structure.
Dijkstra’s algorithm is a way to find the shortest path from one vertex to every other vertex in a graph. Here is an implementation in Kotlin.
Java and JavaScript are two of the most popular languages out there. On the surface, their execution is very different—one being interpreted and the other running on this important platform called the JVM.
Monte Carlo methods originated from the Manhattan Project, as a way to simulate the distance neutrons would travel through through various materials.