How Git Manages Changes

Git is a content-addressable storage system: all data is stored as objects inside the .git directory.
Each object in Git has its hash, which is used for identification.

Let’s see how common commands use Git’s structure to perform various operations.

We will experiment on the httpexpect repository at tag v2.16.0.

How to Run GitLab Runner on Synology NAS

GitLab Runner can be deployed not only in the cloud but also on local devices. One of the most convenient options is using a NAS to execute CI/CD pipelines.

This approach offers several advantages: the NAS operates 24/7, ensuring the Runner is always available; you don’t consume minutes from your `GitLab free plan; and task execution happens directly within your local network, enhancing speed and control.

On my NAS, the primary method for running applications is via containers using docker-compose. Therefore, this method is suitable not only for NAS devices.

We will set it up on a Synology DS423+.

How to View the Latest Database Schema Post-Migrations

When a database schema changes frequently, the project eventually accumulates a large number of migration files.
Each migration covers only a single change - adding a column, modifying its type, renaming a table, dropping an index, and so on.
These migrations may also be implemented differently - some as raw SQL, others in Go code.

Over time they form a long chain, and it becomes non-trivial to understand the actual state of the database at any given moment.
This is especially true if the project evolves quickly or is maintained by several teams.

Things get even more complicated in a multi-service architecture, where each service has its own schema and its own set of migrations.
It’s easy to lose track of which migration belongs to which schema - and understanding the current structure of each database becomes a challenge.

Password Recovery for ZIP Archive Using Hashcat

Goal: recover the archive password.
We will use the hashcat utility to search for the password using a dictionary and mask attack.

Let’s create a test archive containing the secret file flag.txt and set a password on the archive:

# zip -e secret.zip flag.txt

Enter password:
Verify password:
  adding: flag.txt (stored 0%)

HTTP over SSH in Go

A web server is running on a remote machine and is accessible only via localhost; it does not accept external connections. The only way to access this machine is through SSH.

The goal is to implement the ability to send HTTP requests to this web server from within a Go application by establishing an SSH tunnel programmatically.

Web Server in Assembly

To learn Assembly, let’s build a simple web server that simulates a key-value database.

  • The server should support the following endpoints:
    • GET /{key} - retrieve the value for the key.
    • POST /{key} - store the request body as value for the key.
  • The server should support concurrent request handling.
  • The server should persist all data on disk.
  • All server code must be written in Assembly.

Since Assembly is difficult and inconvenient to work with, simplifications are allowed.

How to Restore Data from a Backup in PostgreSQL

Sometimes there’s a need to create a PostgreSQL backup using readily available tools and restore this backup into another database, for example, for testing purposes.
We will use the pg_dump and pg_restore utilities to achieve this.

Depending on the specifics, there are other solutions too, such as connecting a replica or using logical subscriptions.
However, these may require administrative privileges that are often not available when using cloud infrastructure.

We’ll also refresh our memory on working with Docker and SQL.

We’ll use a remote database on Vercel via the Neon service.
Neon is a cloud-native, serverless-compatible PostgreSQL platform.

Julia Set Fractals - Graphics with Ebiten Library in Go

Sometimes you need to visually represent some simulation or process.
The main requirements are support for the Go language, since calculations are done in Go, and ease of use.

Let’s look at ebiten, one of the most popular libraries for working with graphics.
The main use of ebiten is creating interactive 2D games.

We will use the library to draw some dynamic process.

As an example, let’s try to draw the Julia set.

The Julia set is described by the equation
J(f)={zClimnfn(z)+} J(f) = \left\{ z \in \mathbb{C} \mid \lim_{n \to \infty} |f^n(z)| \neq +\infty \right\}

where $ f(x) = z^2 + c, c \in \mathbb{C} $

How to Intercept and Decrypt TLS Traffic from curl

Sometimes, for debugging purposes, you may want to inspect the contents of HTTPS traffic.
For example, a client uses cURL to communicate with a public API server.
But sometimes something goes wrong. The client doesn’t receive a response, even though the server logs show the request was successfully processed and a response was sent. It seems something is getting lost among various proxies and subnets.
In such cases, you can try capturing network activity between the client and the service at different points, decrypt the data, match the requests and responses, and check whether anything was lost.

Advent of Code 2024

Advent of Code 2024 has successfully concluded!

Every day from December 1 to 25 came with two new tasks.
The first task was usually simple, helping to understand the problem clearly.
The second task was harder, with changes or new rules that made the first solution useless.
This often meant improving the algorithm a lot or finding a completely different way to solve it.

The first half of the tasks was relatively simple, while solving the final challenges required some hints.

Overall, it was an excellent opportunity to revisit and apply algorithms.

LeetCode - One-Year Challenge

The challenge of solving daily problems on LeetCode for a year (excluding vacations) has come to an end.

Over the year, I solved 707 problems, categorized as follows: 261 Easy, 365 Medium, 81 Hard.

I mainly focused on daily challenges and “favorite” topics. The most interesting topics were Trie, Dynamic Programming, and Design.

Almost all problems were solved using C++, though I also experimented with Go. However, Go proved unsuitable for algorithmic problems due to its limitations. In contrast, C++ offers a much broader range of concepts, enabling more elegant and optimal solutions.

I took on these problems to prepare for algorithmic interview sections, all of which I passed successfully.

Going forward, I don’t plan to focus on algorithmic problem-solving anymore. If I feel like tackling challenges, I’ll turn to CTF problems, which are far more practical and diverse.

amyasnikov - LeetCode Profile

My profile: amyasnikov - LeetCode Profile