<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Just alex on Medium]]></title>
        <description><![CDATA[Stories by Just alex on Medium]]></description>
        <link>https://medium.com/@__alex__?source=rss-9a05bb51d922------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*9_G0Vpo6kgOYyVegjvqz9Q.jpeg</url>
            <title>Stories by Just alex on Medium</title>
            <link>https://medium.com/@__alex__?source=rss-9a05bb51d922------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 21:57:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@__alex__/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Not Our Fault. Part 2: Rituals]]></title>
            <link>https://medium.com/@__alex__/not-our-fault-part-2-rituals-06461cca45bf?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/06461cca45bf</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[bugs]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Wed, 29 Apr 2026 10:08:32 GMT</pubDate>
            <atom:updated>2026-04-29T10:08:32.046Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*ymMAkrNPVTV_4dNY4vm8DQ.jpeg" /></figure><p>Hey folks!</p><p>Shame on me, I’ve been working damn hard last month, as well as doing hundreds of other things in between. Even now I’m walking from work to the gym, so sorry for not spamming your feed with numerous articles. I will be a better spammer eventually.</p><p>Today is part 2 of stupid mistakes made not by us programmers. They are fundamental, by design, and this time it’s not just bad naming. It’s about rituals we’re forced to do — or get punished if we refuse to.</p><h3>Enabling “normal mode” in bash</h3><p>By default, Bash works as a non-stoppable machine:</p><ul><li>Current command failed? Fuck it, go on to the next one.</li><li>Current command produced an error? Fuck it, feed the garbage to the next command via pipe.</li><li>Some variable is undefined? Fuck it, let’s assume it’s empty.</li></ul><p>C’mon, the last thing you want your program to do is fail at some point, generate garbage, and continue working with that garbage. But that’s what bash does by default!</p><p><strong>The ritual:</strong> every bash script must start with set -euo pipefail.</p><ul><li>-e makes bash stop if some command fails;</li><li>-u forbids using unset variables;</li><li>-o pipefail — pipeline fails if any command within it fails.</li></ul><p>If you ever forget this ritual, shit will hit the fan, severely. For example:</p><ul><li><a href="https://www.youtube.com/watch?v=kUtarOlOT3Y">Cloudflare going down</a> because garbage was piped down the pipeline</li><li><a href="https://www.youtube.com/watch?v=Nkm8BuMc4sQ">Entire Kyoto University database wiped</a> due to an undefined variable treated as an empty string</li></ul><h3>Dumb substitution</h3><p>The root cause of many mistakes is “dumb substitution”. By that term I mean exactly what it sounds like: putting one string into a placeholder as-is. It backfires. Here are some cases.</p><h4>SQL injections</h4><p>SQL injections are a direct result of putting values straight into the query.</p><pre>SELECT * FROM users WHERE id={USER_INPUT};</pre><p>Substitute USER_INPUT with 123; ANY COMMAND and run whatever you want.</p><p><strong>The ritual:</strong> use ORM or parameterized queries, otherwise you’re doomed.</p><h4>C macros</h4><p>Dumb simple macros:</p><pre>#define SQR(x) x * x<br>int b = SQR(1 + 2);</pre><p>This expands to:</p><pre>int b = 1 + 2 * 1 + 2;</pre><p>And suddenly your macro calculates God knows what.</p><p><strong>The ritual:</strong> use parentheses around your macro, otherwise you’ll have a lot of fun debugging random values.</p><h3>Secret key in sources</h3><p>I love Django for many things, and one of them is that when you run a startproject command, it creates a new project and puts SECRET_KEY directly into your code. Like, you spend your entire career trying not to fuck things up, not to leak secrets, to isolate them; GitHub invents action secrets, AWS invents secret variables; but Django just says &quot;screw it all&quot; and puts your secret right into the code, forever. Thanks, mate!</p><pre>&gt; django-admin startproject myproject<br>&gt; cat myproject/settings.py | grep -i secret<br># SECURITY WARNING: keep the secret key used in production secret!<br>SECRET_KEY = &#39;django-insecure-m&amp;!$#k(56asdf_example_random_string_89123&#39;</pre><p>Thanks for starting it with django-insecure. You could also put delete-this-secret inside the key, everyone will definitely see it, right?</p><p><strong>The ritual:</strong> create a project, replace SECRET_KEY = os.environ(&quot;DJANGO_SECRET_KEY&quot;), otherwise your key is baked into your code.</p><h3>Creating async tasks in Python</h3><p>When you create an async task in Python with asyncio.create_task(), you probably expect the task to… run. Bold assumption. But Python has other ideas. If you don&#39;t keep a reference to the created task, it may get <a href="https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task">wiped by the garbage collector</a> at any moment. &quot;No reference in code&quot; = &quot;not needed&quot;. That&#39;s how computers think, not humans. Humans think that if a task was created, it should execute (feels like I’ve said that already).</p><p><strong>The ritual:</strong> save the task somewhere. Happy debugging if you forget.</p><pre>tasks = []<br># ...<br>def func():<br>    task = asyncio.create_task(do_stuff())<br>    tasks.append(task)  # &lt;-- this</pre><p>The more you go through an engineer’s career, the more rituals you collect. The more rituals you collect, the more likely it is that you forget one of them. It’s not our fault that we forget things, it’s the fault of those who keep adding to that enormous ritual list.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*69vOHDtrmlbRTEUAYKFTxg.png" /></figure><p>If you want to check how many rituals I remember — and, more interestingly, how many I forget — <a href="https://flowcv.com/resume/eafjjcsudb">hire me</a>. Or sign a contract with <a href="https://slashhash.dev/">SlashHash.dev</a> if you’re into B2B stuff.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=06461cca45bf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Not Our Fault. Part 1: Stupid Names]]></title>
            <link>https://levelup.gitconnected.com/not-our-fault-part-1-stupid-names-ae9a257ee844?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/ae9a257ee844</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[bugs]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Wed, 18 Mar 2026 15:13:20 GMT</pubDate>
            <atom:updated>2026-03-18T15:13:20.916Z</atom:updated>
            <content:encoded><![CDATA[<p>Welcome to a series of articles called <em>“Not Our Fault”</em>, where I show bad design decisions and all sorts of bugs they lead to.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*_yUqrHCn-VP3kjbxxcQUZQ.jpeg" /></figure><p>When building a house, you start with the foundation. It is important to make it solid for two reasons:</p><ul><li>if you make it weak, it will ruin everything you build on top of it, no matter how amazing it is</li><li>fixing it would require an enormous amount of effort, if it’s even possible</li></ul><p>The same applies to programming. When you want to write some code, you don’t start with metal and silicon. You use hardware and technologies already created by someone else, and that becomes your foundation. And the quality of this foundation affects everything built on top of it.</p><p>Recently I started noticing cracks in these foundations. Guys, they’re everywhere! And more importantly, they affect all those beautiful houses built on top. We write code, but it breaks because the foundation is weak.</p><p>It’s not our fault.</p><p>Lemme show you.</p><p>Let’s talk about stupid names in this part.</p><p>Naming things is important. If you name a place “<a href="https://en.wikipedia.org/wiki/Taumatawhakatangi%C2%ADhangakoauauotamatea%C2%ADturipukakapikimaunga%C2%ADhoronukupokaiwhen%C2%ADuakitanatahu">Taumatawhakatangihangakoauauotamatea­turipukakapikimaungahoronukupokaiwhenuakitanatahu</a>”, you make trouble for people trying to spell it. If you give two subway stations the same name, people will fail to meet all the time — I’ve seen it in real life. Naming things in a confusing way leads to mistakes.</p><p>Programming is no exception.</p><p>In Python, we have re.finditer() to find all occurrences of some pattern. We also have a somewhat similar re.findall() (what for? I have no clue!). Now you want to find a single occurrence — how do you do that? Well, take the first result of re.findall() or re.finditer(), right? No, you fool! Python has a separate function for that, and it&#39;s called… no, not re.find(). What’s wrong with you? It’s called re.search()!</p><p>To remember, here’s the rule:</p><ul><li>If you want to FIND one occurrence, use re.search</li><li>If you want to SEARCH for many occurrences, use re.find</li></ul><p>Easy-peasy!</p><p>Now you want to work with a database and instantiate PostgreSQL. Which databases are there by default? Yeah, as you would expect: postgres, template0, template1. Now try to guess what they are for. What if I named them default, frozen_template, and template? See, it’s much better with better names!</p><p>Aside from just choosing bad names, one can simply choose the same names. In Linux, there are useradd and adduser commands. They are different. I always prefer one of them, but I don’t remember which one! There are also groupadd and addgroup.</p><p>In addition to the name clash, useradd has flag clashes as well:</p><pre>-g, --gid GROUP          name or ID of the primary group of the new account<br>-G, --groups GROUPS      list of supplementary groups of the new account<br>-m, --create-home        create the user&#39;s home directory<br>-M, --no-create-home     do not create the user&#39;s home directory<br>-p, --password PASSWORD  encrypted password of the new account<br>-P, --prefix PREFIX_DIR  prefix directory where are located the /etc/* files</pre><p>Try not to confuse -p and -P: the password is not important, so it gets the “small letter p”, and the prefix is really important (you always change prefixes, right?), so it gets the “big letter P”. Maybe. And nobody really knows what will happen if you write useradd --create-home --no-create-home. Maybe the universe will collapse.</p><p>Want more similar names for different things? git checkout &lt;branch&gt; switches to the selected branch, while git checkout -- . resets all unstaged changes. Don’t ask, just remember.</p><p>On the opposite side, there is also the opportunity to take two similar things and name them as differently as possible! Just like in CSS:</p><pre>justify-content: center; /* center horizontally */<br>align-items: center; /* center vertically */</pre><p>Another example of similar things with different names? Sure — git is a champion here! git switch &lt;branch&gt; is the same as git checkout &lt;branch&gt;. Pick one depending on your mood.</p><p>The examples above mostly just slow developers down by confusing them. But can bad naming do something destructive? Sure thing!</p><p>In JavaScript, they have a method that checks whether a pattern matches, and they decided to name it test():</p><pre>&gt; const regexp = /1234/<br>&gt; regexp.test(&quot;12345&quot;)<br>true</pre><p>What if someone one day forgets that test() does not actually test the whole thing, but just the beginning? Well, that someone <a href="https://www.youtube.com/watch?v=dOgWVdWqXRU">could expose the AWS JS SDK repository</a>, because an account ID check would compare only the start, granting access not only to account 1234 but also to 12340, 12341, 12342, etc. Isn’t that nice?</p><p>Python also wanted to add some delightful confusion. strip(&quot;something&quot;) will strip the letters &quot;s&quot;, &quot;o&quot;, &quot;m&quot;, &quot;e&quot;, &quot;t&quot;, &quot;h&quot;, &quot;i&quot;, &quot;n&quot;, and &quot;g&quot; from the beginning and end of a string. &quot;ethereum&quot;.strip(&quot;something&quot;) results in &quot;reu&quot;, and I absolutely love how confusing that is! A classic example is url.strip(&quot;https://&quot;), which looks harmless but behaves unpredictably.</p><p>One of my favorites is Bash’s &amp;. Look:</p><ul><li>&amp;&amp; is logical AND, letting you combine the results of two commands</li><li>&amp; runs a process in the background</li></ul><p>Yeah, just one more symbol triggers completely different functionality! So instead of writing A &amp;&amp; B — which runs A and then B — people write A &amp; B, which launches A in the background and immediately launches B. I suspect everyone who’s ever written something in Bash has made this mistake. I sure did.</p><p>See the pattern? These errors happen because programmers make them, sure — but only because the mistakes were possible, practically handed to us by design! That’s why it’s called <em>“Not Our Fault”</em> — most of the time, we’re just conductors, delivering someone else’s chaos straight into production.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*3zajxR6zqt7YWjOVIOZgcQ.png" /></figure><p>I can carry bad design straight into your project and make it explode! Oh, wait… something’s wrong. Ah, I got it backwards — I’ll actually make your project just work as intended, without unexpected outages. Boring, I know. But if you’re into boring, working things, <a href="https://flowcv.com/resume/eafjjcsudb">I’m the person to hire</a>, and <a href="https://slashhash.dev">SlashHash.dev</a> is the company to call.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae9a257ee844" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/not-our-fault-part-1-stupid-names-ae9a257ee844">Not Our Fault. Part 1: Stupid Names</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[It’s Not Just About Writing Code]]></title>
            <link>https://levelup.gitconnected.com/its-not-just-about-writing-code-29d0522c2d25?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/29d0522c2d25</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[startup]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Mon, 09 Mar 2026 14:49:20 GMT</pubDate>
            <atom:updated>2026-03-09T14:49:20.346Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*EZkwbkWAfuioIWoRbWosZQ.jpeg" /></figure><p>I know some people who follow me (thanks, folks!) aren’t really into IT. Maybe some of you are curious about what programming actually is. And no, it’s not just about writing code — it’s much, much more. Let me show you in four short points.</p><p>So, as I said, writing code isn’t a big deal by itself. Especially now, when you can ask large language models to spit it out for you. The real deal is everything around it.</p><h3>Taking responsibility</h3><p>Developers don’t just deliver code. They deliver <strong>working, maintainable</strong> code <strong>that they are responsible for</strong>.</p><p>In the era of so-called “AI”, it’s very tempting to offload the writing part to LLMs. But responsibility isn’t something you can outsource. In the worst case, the model will just shrug and say something like, <em>“Oh sorry, you’re right, I completely ruined your business with that code — let me rewrite it.”</em></p><p>Have you ever seen OpenClaw’s <a href="https://www.youtube.com/watch?v=JiA4fvoeUfI">“sorry for deleting all your email, won’t happen again”</a>? That pretty much sums it up. AI doesn’t really care. People do.</p><p>Another thing to remember: all these models are trained on code scraped from all over the internet. In a sense, they’re an average of that code. And wow, I’ve seen <strong>a lot</strong> of open-source projects with the structural integrity of a rotten potato. <a href="https://github.com/django/django/blob/787166fe27b0e7c7f97505da5766cfa72e76ae25/django/contrib/admin/options.py#L1386">Django</a>, <a href="https://github.com/BerriAI/litellm/blob/6621c7b2ef78b3b0b9f59bc64711f789ef66ed3c/litellm/main.py#L1014">Litellm</a>, LangChain… you name it.</p><p>So here’s the funny part: we train models on piles of messy, unmaintainable code — and then act surprised when they produce messy, unmaintainable code.</p><p>Garbage in, garbage out. The old law of computing is undefeated.</p><h3>No trust</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RRwZEk1XOGHhV5On" /><figcaption>Photo by <a href="https://unsplash.com/@brucemars?utm_source=medium&amp;utm_medium=referral">bruce mars</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>I don’t trust AI-generated code. I don’t trust my coworkers’ code either — people make mistakes, and a couple of code reviews is usually enough to prove that.</p><p>Honestly, I don’t even fully trust my own code.</p><p>I’ve seen enough reviews on things I wrote to know that I mess up too. The real question isn’t <em>“Do I make mistakes?”</em> Of course I do. The real question is: <em>“How many mistakes do I make per 100 lines of code, and how do I reduce that number?”</em></p><p>The same skepticism applies to new technologies. “New” doesn’t automatically mean “better.” Skepticism is a feature, not a bug.</p><p>Sure, I know <a href="https://fastapi.tiangolo.com">FastAPI</a>, <a href="https://litestar.dev">Litestar</a>, even <a href="https://github.com/dymmond/ravyn">Ravyn</a>. But for a new project I’ll still pick Django. That beast has been around for decades, and it works. Not because it looks nice on a landing page — because it’s been tested in the wild.</p><p>Think of it like driving through the wilderness. I’d probably take an old, reliable Ford over a shiny new Tesla. Tesla is cool, no doubt about it. But when you’re in the middle of nowhere, you want something you <strong>know</strong> will start.</p><p>Maybe one day I’ll try something new. When I have enough optimism… and free time.</p><p>Trust no one — and you’ll end up building something reliable.</p><h3>Fighting the unknown</h3><p>The world of IT moves at a ridiculous pace. Stuff gets invented, updated, broken, and fixed — sometimes all four within the same month. If you work in this field, you’re basically signing up to learn forever.</p><p>And code doesn’t live in a vacuum. It needs infrastructure — the environment where it actually runs. And chances are, you’ll have to learn that too.</p><p>I’ve been programming for about 15 years, and the last time I learned something new was… yesterday.</p><p>This time it was about getting structured logs from my code into Loki, and then figuring out how to display those logs nicely next to charts in Grafana. Not really coding. Still had to learn it.</p><p>That’s the job. You keep fighting the unknown, one weird problem at a time.</p><h3>Go beyond</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*YV1kdm1jVFBNxmgL" /><figcaption>Photo by <a href="https://unsplash.com/@tejjj?utm_source=medium&amp;utm_medium=referral">Tejj</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>As I mentioned earlier, programming is way more than just writing code. And it’s even more than dealing with infrastructure or learning new tools. A big part of the job is stepping back and looking at the bigger picture.</p><p>Have you heard of the infamous <a href="https://en.wikipedia.org/wiki/XY_problem">XY problem</a>? That’s when a client has a problem, but thinks they already know the correct solution. So they come to a developer and ask for that specific solution to be implemented.</p><p>The novice path — and honestly the typical AI path — is simple: just do what you were told.</p><p>The professional path is different. You try to figure out the <em>actual</em> problem and then propose the best solution you can think of.</p><p>I’ve seen plenty of situations where a client asked for something inefficient simply because they didn’t see the whole picture. And to be fair, they’re not supposed to. That’s part of my job.</p><p>My responsibility is to zoom out and see the whole landscape of possibilities.</p><p>So you can probably guess that I’m not really afraid of AI taking my job — at least not anytime soon. AI mostly writes code, while for me writing code is just one small part of the job.</p><p>And I’m pretty sure the same idea applies to many other professions too:</p><ul><li>AI can generate music, but it still struggles to create <a href="https://www.youtube.com/watch?v=s_nc1IVoMxc">something that genuinely gives you goosebumps</a>.</li><li>AI can act like a psychologist, but it rarely disagrees with you — which can trap people in a <a href="https://medium.com/@ChrisDevAI/ai-validation-loop-how-people-could-become-trapped-in-feedback-loops-with-language-models-4ce69b36629f">destructive validation loop</a>.</li><li>AI can help with legal work… right until it <a href="https://www.reuters.com/legal/government/us-appeals-court-orders-lawyer-pay-2500-over-ai-hallucinations-brief-2026-02-18/">hallucinates a case</a> instead of actually finding one.</li></ul><p>We’re humans. When we do our jobs, there’s usually <strong>a lot</strong> happening beneath the surface. Judgment, responsibility, experience, context — the invisible stuff that never shows up in a prompt or an API call.</p><p>And that’s the invisible stuff that matters most.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*3zajxR6zqt7YWjOVIOZgcQ.png" /></figure><p>You can’t see all the invisible stuff, but you <em>can</em> see the results. With <a href="https://slashhash.dev">SlashHash.dev</a>, those results usually show up in just a few weeks.</p><p>Oh, and <a href="https://flowcv.com/resume/eafjjcsudb">here’s my CV</a> — take a look!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=29d0522c2d25" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/its-not-just-about-writing-code-29d0522c2d25">It’s Not Just About Writing Code</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Burn It and Start Over]]></title>
            <link>https://levelup.gitconnected.com/burn-it-and-start-over-e1cfe208e35b?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/e1cfe208e35b</guid>
            <category><![CDATA[cognitive-bias]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[project-management]]></category>
            <category><![CDATA[time-management]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Fri, 20 Feb 2026 12:40:28 GMT</pubDate>
            <atom:updated>2026-03-02T15:23:15.064Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Zm7ZSG2cfOox31ohanWiRg.jpeg" /></figure><p>Happens all the time. You fill out an online quiz, and instead of showing the results it asks for your email. Or a scammer tells you to send money one last time (“it’s the final fee, I swear!”) before you can withdraw your earnings — which, of course, is never going to happen.</p><p>These are classic examples of a cognitive bias called the Concorde effect. You’ve already invested time or effort into something, and it feels painful to walk away. Even when quitting is the only logical move, that feeling pushes you to keep going just a little longer.</p><p>And honestly, that’s fine. All these little brain glitches are part of being human.</p><p>But sometimes those glitches work against us — quietly and automatically. I’ve noticed the same pattern in programming, so here are a few stories, starting small and getting bigger, where you can see it in action. Enjoy.</p><h3>10 Minutes</h3><p>During a time-limited screening test for a job, I got a simple task: write a regular expression for a (non-shortened) MAC address. For non-technical readers, here’s the translation: strings like <em>00:1A:2B:3C:4D:5E</em> or <em>00:1B:63:84:45:E6</em>, and I had to describe them with a rule.</p><p>My first attempt looked like this:</p><pre>[0–9A-F]{2}:[0–9A-F]{2}:[0–9A-F]{2}:[0–9A-F]{2}:[0–9A-F]{2}:[0–9A-F]{2}</pre><p>Just “two letters or digits, then a colon, then two letters or digits, then a colon, then two letters or digits, then a colon, then two letters or digits, then a colon, then two letters or digits, then a colon, then two letters or digits”.</p><p>Does it work? <strong>Yes.</strong> Is it painfully dumb? <strong>Also yes.</strong></p><p>Then I started thinking: this is a senior developer position. I should probably demonstrate some elegance. Something clever.</p><p>The clever version would say: “two letters or digits followed by a colon, repeated 6 times — except the last time, when there’s no colon.” That “except the last time” part is where I got stuck. For humans it’s trivial. For computers — and especially regular expressions — exceptions are… exceptional. So I spent maybe 5–10 minutes googling and trying to come up with something short, beautiful, and suitably senior-looking.</p><p>Eventually I decided: screw it. Screw the research, screw the elegance. The answer is ugly, but it <strong>is</strong> an answer, and it works.</p><p>I passed the test.</p><p>Turns out elegance wasn’t the point. Instead of getting stuck polishing an almost-nice solution, I saved time for the rest of the tasks. I spent ten minutes and threw them in the trash — and that was actually the right decision.</p><p>But ten minutes is just ten minutes. Let’s scale this up a bit.</p><h3>6 Hours</h3><p>Once upon a time a client asked me to add a dozen new fields to his app. I’ll simplify the story a bit. It was a sports app with fields like football, basketball, tennis, and so on, and he wanted to expand the list.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*v6vdIEbs1iFezlH8" /><figcaption>Photo by <a href="https://unsplash.com/@vikramtkv?utm_source=medium&amp;utm_medium=referral">Vikram TKV</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>It wasn’t the first time the client had asked for something like this, and hardcoding all those footballs and basketballs into the source code was starting to look pretty ugly — imagine fifteen of them scattered everywhere. It felt like the perfect moment to introduce EAV.</p><p>EAV is not the name of an ancient beast. It stands for <em>Entity–Attribute–Value</em>. Instead of an entity having a fixed set of fields like “football” and “basketball” and nothing else, it can have as many attributes as needed — created by the client, not by me. Instead of messaging “hey Alex, do some coding again,” he could just click a few buttons in the admin dashboard and instantly get whatever he wanted — even alien MMA fights or cockroach races. EAV is flexible and powerful, as long as you implement it properly. So I implemented it. Not a big deal.</p><p>Then another problem surfaced. The database had some internal machinery (a “database view”) that aggregated statistics, and it had football, basketball, and the rest hardcoded all over the place. Since those were going away, I had to refactor the view. Not a big deal.</p><p>Then I discovered that the JavaScript code powering the interactive parts of the site was broken because — you guessed it — it also had football and basketball everywhere. Fine. I fixed that too. Not a big deal.</p><p>Six hours later I was still fixing “not a big deal” problems. Each fix brought the system <em>almost</em> back to life, but something else always broke. Every time it felt like the final step, it wasn’t. There was always one more thing.</p><p>So I burned it.</p><p>It hurt after six hours of work, but I ran git checkout -- ., wiped out all the changes, and started over. No EAV, no refactoring — just alien MMA fights and cockroach races, exactly as the client asked. The code got a little uglier, but the task was done.</p><p>How many more hours would it have taken if I hadn’t stopped? Nobody knows.</p><h3>2 Months</h3><p>We once built an app from scratch that started as a tiny automation script. At the time I told the client, “Let’s run it on AWS Lambda — it’ll cost basically $0.” Perfect.</p><p>Then the client realized he needed to store some data, so I said, “Let’s add DynamoDB. Still basically $0, and it’ll do the job.” Great.</p><p>Then he needed a user interface. So we added that too.</p><p>At some point I had to admit that if we kept piling features onto our poor little automation script, it would turn into an unmaintainable monster. It wasn’t a small script anymore, and we needed a different architecture — and different tools — to handle what the app had become.</p><p>The client was perfectly reasonable about it. We threw away the Lambda function, DynamoDB, and everything else we had accumulated over two months, and rewrote the whole thing.</p><p>It felt like a step backward. I had to rebuild functionality that was already working. But that step back let us move much faster afterward.</p><p>Sometimes you have to drop ballast to fly higher.</p><h3>2 Years</h3><p>American startup. We were working on advanced text processing and recognition. Today problems like that can be solved in seconds by modern LLMs, but back then it was closer to rocket science — unexplored territory.</p><p>Natural language processing. Machine learning. Scraping and normalization. Hyperparameter tuning. Custom algorithms. We tried everything we could think of to make it work.</p><p>It didn’t.</p><p>Some parts worked, technically speaking, but the overall quality was too low. It wasn’t enough to capture the market. And this went on for two long years.</p><p>One day I told my employer: this just doesn’t work. Unless you have some secret technology or a hidden genius waiting in the wings, we’re not going to make it. We’ve tried too much already.</p><p>For me, <em>“we’ve tried too much”</em> was a verdict. For him, it was an anchor. And I understand — it’s incredibly hard to abandon a project you’ve poured years of time and money into and start something completely different. He couldn’t do it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*eWyHq6saGI2eQC1O2XjowQ.jpeg" /></figure><p>So I left the company. Later I heard the project kept going. Did it succeed? I seriously doubt it. And I’m glad I got off that sinking ship.</p><p>Even if it somehow stayed afloat, it would have been wiped out anyway by the tsunami called LLMs.</p><p>See the pattern?</p><p>When you move through the labyrinth called life, sometimes you hit a dead end. And the moment you see it, be honest with yourself and admit what it means: dead ends lead nowhere, no matter how long the road was. Accept the loss.</p><p>Burn whatever you built before, and start over.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*uS-oIxweSHejIuYyJlXseg.png" /></figure><p>Want me to burn your project? Hire me.</p><p>Just kidding — I won’t burn it. I’ll make it shine. I turn startup ideas into reality fast. If you want to get in touch, check out <a href="https://slashhash.dev">SlashHash.dev</a> or <a href="https://flowcv.com/resume/eafjjcsudb">my CV</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e1cfe208e35b" width="1" height="1" alt=""><hr><p><a href="https://levelup.gitconnected.com/burn-it-and-start-over-e1cfe208e35b">Burn It and Start Over</a> was originally published in <a href="https://levelup.gitconnected.com">Level Up Coding</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I saw many startups killed by this one thing]]></title>
            <link>https://medium.com/@__alex__/i-saw-many-startups-killed-by-this-one-thing-70e9f7ea9ca8?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/70e9f7ea9ca8</guid>
            <category><![CDATA[time-management]]></category>
            <category><![CDATA[business]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[startup]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Thu, 12 Feb 2026 09:05:35 GMT</pubDate>
            <atom:updated>2026-02-20T13:12:14.430Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NqKitZqO6WM1FoKIFFZ_Rw.jpeg" /></figure><p>I’ve been working as an independent contractor for over a dozen years. Naturally, a lot of those projects were startups.</p><p>A biomedical monitoring web app. A gig organization portal for musicians and singers. Massive data analytics for the US real estate market.</p><p>A good chunk of them failed.</p><p>After seeing this movie enough times, I started noticing a pattern. The startups that crashed and burned had something in common.</p><p>But lemme tell you a story first.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*J8dmde2LF7QunGye" /><figcaption>Photo by <a href="https://unsplash.com/@originspoker?utm_source=medium&amp;utm_medium=referral">Dylan Clifton</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>There was this cool guy who wanted to build an app to teach people how to play poker — and actually win. The “win” part is important. Anyone can memorize the rules. Consistently making money is where things get interesting.</p><p>He’d built a really smart math engine that could look at a table situation and suggest what kind of move would make sense. Not a cheating tool — nothing shady running under the table. This was meant for learning and training. You’d study hands, explore scenarios, understand why one decision beats another. Think gym for your poker brain.</p><p>I can’t share the details because of an NDA, but the key point is this: he had a clear goal, and the idea was strong. There’s always a crowd of players who want to level up, and this app aimed straight at that niche — more focused and practical than the existing options.</p><p>On paper? Beautiful startup.</p><p>So he hired a backend team (I was one of them), a frontend/app team, and a project manager. The engine was on.</p><p>I don’t know much about what the frontend folks were doing day to day. I just know they designed screens in Figma and turned them into some shiny modern frontend framework, complete with all the bells and whistles. Or whistles and giggles. Either way, they had plenty on their plate.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*l7IvVQbz5L4_Eyxb" /><figcaption>Photo by <a href="https://unsplash.com/@uxindo?utm_source=medium&amp;utm_medium=referral">UX Indonesia</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>I didn’t see much of the frontend world, but I knew our backend inside out.</p><p>First thing we built? A monstrously large subscription system. Recurring payments sound simple until you actually try to implement them. Then you discover that “subscription” is a polite word for a hydra.</p><ul><li>It can be recurring or one-time</li><li>It can have a trial period</li><li>It can apply discounts based on weird conditions</li><li>It can be paused, resumed, canceled, partially refunded, fully refunded, retroactively adjusted, and probably judged by a higher court</li></ul><p>This is not a “couple of evenings with pizza” feature. This is a full-blown subsystem.</p><p>We made it a unified layer over multiple payment providers: Google in-app purchases, App Store purchases, and some Stripe-like service. Having one clean interface for all of them is great. Being the person who has to build that abstraction is… not so great.</p><p>And because life wasn’t complicated enough, every payment provider has its own “unique” logic. Unique as in: completely different from every other provider on Earth. Different event flows, different validation rules, different edge cases. My job was to translate that zoo into one coherent system. I suffered.</p><p>On top of that, we used Firebase alongside our regular database. Why? Because the expectation was tens of thousands of users. And 10 users and 10,000 users are two different universes. With 10 users, bad architecture politely whispers. With 10,000, it explodes like a dying star.</p><p>So we tried to offload as much as possible into Firebase as a fast-access layer in front of the main database. Setting it up felt like reverse-engineering alien technology. The available operations were oddly limited, the patterns were… unconventional. It took effort to make it behave as a proper first line of defense. But eventually, we made it work.</p><p>And “eventually” is the key word here.</p><p>In a regular long-term project, long coding sprints are fine. You polish, you refactor, you build infrastructure. Startups don’t live in that luxury. They have limited time and limited money. The rule is simple: build a minimal viable product, launch it, gather feedback. Then improve, launch again, gather feedback. Repeat.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZdFU767r1_hpbpetSFB_2g.jpeg" /></figure><p>Small steps toward a big goal. Not a heroic jump straight to the finish line.</p><p>That project chose the jump. We spent a lot of time and a lot of money polishing everything. Infrastructure solid. Payments flawless. Architecture ready for tens of thousands of users. We were prepared for a crowd.</p><h3>Day X arrived.</h3><p>No thousands. Not even hundreds. A few dozen.</p><p>The app worked. Technically, it was fine. It just… didn’t matter. Nobody noticed.</p><p>And that, by itself, is not a tragedy. Startups flop quietly all the time. Maybe the marketing missed the mark. Maybe the demand wasn’t really there. Maybe the world just shrugged. That’s part of the game.</p><p>The real problem is timing.</p><p>If you discover there’s no traction after a week with a rough prototype, you pivot. You adjust. You survive.</p><p>If you discover it after months of development, with a “perfect” product and an empty bank account, that’s not feedback. That’s a postmortem.</p><p>That’s how startups die.</p><p>Perfection is a luxury item, startups can’t afford it. You don’t begin with marble columns and gold trim. You begin with something slightly ugly that works. You test it in the wild. You let reality punch it in the face.</p><p><strong>Start imperfectly.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*3zajxR6zqt7YWjOVIOZgcQ.png" /></figure><p>Ad time.</p><p>Even though my paycheck doesn’t depend on a project’s success — I get paid either way — it still feels wrong when months of code quietly fade into irrelevance. Watching something you built with care become “well… never mind” is not exactly motivating.</p><p>So now I work with a team that does things differently. We focus on delivering solid, high-quality MVPs in weeks, not months. Something real. Something testable. Something that meets reality early, not after the budget is gone.</p><p>If that sounds like the smarter path, talk to us at <a href="https://slashhash.dev">SlashHash.dev</a>.</p><p>Or <a href="https://flowcv.com/resume/eafjjcsudb">hire me</a> as a contractor.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=70e9f7ea9ca8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The invisible wall that waited for me for 20 years]]></title>
            <link>https://medium.com/@__alex__/the-invisible-wall-that-waited-for-me-for-20-years-5afc0f539562?source=rss-9a05bb51d922------2</link>
            <guid isPermaLink="false">https://medium.com/p/5afc0f539562</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[game-development]]></category>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Just alex]]></dc:creator>
            <pubDate>Tue, 27 Jan 2026 11:56:11 GMT</pubDate>
            <atom:updated>2026-02-03T12:48:50.180Z</atom:updated>
            <content:encoded><![CDATA[<h3>The Invisible Wall That Waited for Me for 20 Years</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EcSfGv-VxA1YQNcemsK0-Q.jpeg" /><figcaption>Frame from “Under the Dome”, 2013–2015</figcaption></figure><p>When I get moping, I drop everything and write my own game engine. It’s a thankless task, but I like it.</p><p>At the very beginning I had a simple plan: whoosh, whoosh, get a pot, throw in all sorts of libraries for graphics, physics and sounds, add a network library to taste, mix everything with some messaging system, and it’s done. A 15 minute adventure.</p><p>And here I am five years later.</p><p>Well, to be honest, I barely spent any time actually developing, because I kept tripping over all sorts of bugs that drove me mad: serialization didn’t work with inheritance, threads refused to share memory properly, language updates broke compatibility… I could write a whole trilogy about fighting with a game engine. All of this demotivates me, because I want to finally get down to business instead of fiddling with bytes.</p><p>This isn’t my video, but it very accurately captures how I have development going on:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fwww.youtube.com%2Fembed%2F9g3RPbRhMaQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fwww.youtube.com%2Fwatch%3Fv%3D9g3RPbRhMaQ&amp;image=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fi.ytimg.com%2Fvi%2F9g3RPbRhMaQ%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/04d782df6a81302fbaa61eef02ab27d6/href">https://medium.com/media/04d782df6a81302fbaa61eef02ab27d6/href</a></iframe><p>On the other hand, when you finally solve these problems, you feel like a god — like the undisputed king of life — and suddenly you want to program again. For a brief moment, it even feels as if that was the last obstacle. Ha. Naive.</p><p>But I like it. It’s a bit like mountain climbers choosing to suffer their way up a peak when they could just go to a bar with friends and have a beer. Whatever makes you happy.</p><p>I want to talk about one such “obstacle”.</p><p>There’s a physics engine called <a href="https://www.ode.org/">ODE</a> — Open Dynamics Engine. It seems to have emerged sometime in the Paleolithic era. Dinosaurs probably wrote it, and all that remains of the documentation are a few scratches on stone tablets. Still, it works, it’s easy to use, and it comes with C headers. That meant I could write a <a href="https://nim-lang.org/">Nim</a> wrapper and plug it straight into my engine (there’s very little of production-ready libraries in Nim, so the canonical approach is simple: take some C library, learn how to call it, and then proudly tell everyone you wrote a cool program in Nim).</p><p>At first, everything went smoothly. I added a few cubes to the scene and rendered them. The physics engine lived in perfect harmony with the graphics engine: when the renderer showed me walking up to a cube and pushing it, the cube actually flew off and started rotating.</p><p>In short, everything was going exactly according to plan.</p><p>Of course, if you don’t plan to make Minecraft, you may need something more interesting than a cube. ODE has a special Trimesh class that just allows you to make complex geometry. In fact, you can create any body from a set of triangles. Something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eWmS1xAUBPa_D6rd9LXfTA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@dkoi?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">D koi</a> on <a href="https://unsplash.com/photos/a-white-sphere-with-a-black-background-GQJY4UPR21U?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>The machine is stupid, so you can’t just tell it “draw a rock.” You have to say, “here are some vertices, connect them like this, and we’ll call the result a rock”. Naturally, I didn’t take any chances and decided to start with a simple triangle instead of a rock, just to make sure everything worked correctly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*VQaNL2iVBscHzzhOvhflBA.jpeg" /></figure><p>I created the triangle, it successfully rendered on the stage, I started walking around the world… and discovered that the triangle was not where it was drawn, but somewhere else!</p><p>That’s how that stupid invisible wall came to existence.</p><p>In fact, I could walk around the scene, and somewhere I came to the very triangle that actually should have been where it was drawn. I expected something like that, because, as I’ve already written somewhere, only three times in my life I’ve written code that worked the first time. I must have mixed up a coordinate somewhere — maybe I have passed Y instead of X, or vice versa, or something like that. You know programmers!</p><p>I couldn’t draw this triangle, because the coordinates were correct, the graphics engine drew everything correctly, but the physics engine somehow misinterpreted my correct data. So I started walking around the world and trying to determine the outline of this invisible wall. Eventually I found it (it was weird enough), and I decided to move the triangle around a bit to see how it affected this wall.</p><p>It would seem that if I just got the coordinates mixed up somewhere, then moving the triangle would move this wall a little. But no way! The wall disappeared and appeared completely randomly, jumping far away from even the slightest change of coordinates, and I couldn’t understand why.</p><p>And that’s when I remembered one silly scene from some movie! A woman with superpowers turned invisible and decided to hide in the rain. That’s a great plan. That’s f***in’ ingenious, if I understand it correctly. It’s a Swiss f***in’ watch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*3pImWcZGns53vmAgk9h6ng.jpeg" /><figcaption>Frame from “The Defenders”, 2017</figcaption></figure><p>I thought that was my case, so I decided to rain on my wall to see it. I didn’t have any rain, but I had cubes, so I created 50 of them and started throwing them down. When they touched the wall, they stuck to it and I could see its outline. And when you can see something, debugging is much easier!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/854/1*WYcQVbfhxYEZQJmS7YXAkg.gif" /></figure><p>Well… It was a good attempt to figure out what law makes a wall appear where it appears, but it didn’t do anything for me. Even seeing this wall, I couldn’t find any pattern.</p><p>If you need somewhere to find losers like me, the best place to find them is the internet. And I found him — the only person who went through this and wrote about it. Can you believe that in 2006, some dude in Germany had his butt burning just like mine does now!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AEKhqtdeFq2TSN8Qw4F5gw.jpeg" /></figure><p>So… it turns out that the physics engine expects three-dimensional points from you, but you have to pass them as a four-dimensional vector, you just have to put garbage in the fourth coordinate, like this: [x1, y1, z1, 0, x2, y2, z2, 0, ...]. How am I supposed to understand that const dReal* Vertices are <em>four-dimensional</em> vertices?</p><p>That’s why I love opensource — you can always get to the roots of everything. I looked into the source code, and this is what I found.</p><p>In 2003 Russel Smith came in and added all this functionality with trimesh collisions, including the line I was interested in:</p><pre>typedef dReal dVector3[4];<br><br>void dGeomTriMeshDataBuildSimple(<br>    dTriMeshDataID g, <br>    const dVector3* Vertices,  // okay<br>    int VertexCount, <br>    const int* Indices, <br>    int IndexCount,<br>);</pre><p>Everything is clear here, because the definition clearly states that dVector3 is a four-dimensional vector (there is some charm in this logic).</p><p>And then <a href="https://twitter.com/erwincoumans">Erwin Coumans</a> comes in a couple of months later and rewrites it so that the type is not clear anymore:</p><pre>void dGeomTriMeshDataBuildSimple(<br>    dTriMeshDataID g, <br>    const dReal* Vertices,  // wait, wat?<br>    int VertexCount, <br>    const int* Indices,<br>    int IndexCount,<br>);</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q4feDW0yrUx9MEzYGWWspw.jpeg" /></figure><p>And just imagine, 20 years later, this change finds some dude (me) who writes in a different programming language altogether, and makes that dude burn in a futile attempt to figure out why the fuck it doesn’t work.</p><p>I rewrite the code with the fourth coordinate added and everything starts working.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/854/1*9cO1KyjZxJkdU48df1sfvg.gif" /></figure><p>Finally.</p><p>In general, this post was intended to be entertaining, like “look, Alex is suffering again, hahaha”. But I think it raises a rather deep issue: as soon as you post code, it starts its long journey through time. No one knows when or who will read it — maybe you or a colleague in a couple months, maybe thousands of independent developers in a couple years, maybe some guy with a burning production environment.</p><p>You get a kind of butterfly effect, like with this invisible wall. So the next time you sit down to write code, imagine that some developer will be reading it twenty years from now, and try to make that person’s life a little easier. After all, one day that someone might be you.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/268/1*3zajxR6zqt7YWjOVIOZgcQ.png" /></figure><p>By the way, I do software development for a living. If you feel like dumping an irresponsible amount of my expertise onto your project, <a href="https://slashhash.dev">SlashHash.dev</a> is where that happens. Or <a href="https://flowcv.com/resume/eafjjcsudb">check out my CV</a> and just hire me.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5afc0f539562" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>