{
  "items": [
    
    
    {
      "title": "I Do Not Dread Cold Outreach Anymore",
      "content": "I have started doing cold outreach to the people. Initially I use to dread it because the sheer amount of reminders and rejections. The worse is people not responding and even worse is when they say yes but they mean no. It’s kind of like being in an relationship with an indecisive person.\nI want to convince myself that doing cold outreach are a good thing. I myself find it easy to convince myself when I somehow connect it with having an agency. It means that I have full control over it because I am the force behind it hence the control is more solid; as solid as my will.\nThere is a realisation that in startups, things don’t happen but founders make it happen. If you think about it, it’s like having a powerful way to create agency. In the end you want the things to run by themselves but it’s rarely the case at start. By that means I have full control over what happen to us. Isn’t that a good thing?\nNow, I don’t dread doing cold outreach much. I know when I’m doing it, I’m taking control over my results. I follow the rule of being persistant and not being spammy. My intentions around is try to be as helpful as possible. If my solution doesn’t do what client is asking, I say it clearly. If I can build that, I do it and present to them to showcase my commitment to them.\nIf you ever is facing the same situation where you hate cold email, calls, etc. Just remember that you’re taking control of your results. That’s it, have fun doing it!\n",
      "date": "2026-07-02",
      "permalink": "https://iaziz786.com/blog/i-do-not-dread-cold-outreach-anymore/",
      "tags": ["sales","cold outreach","dread","agency"]
    }
    
    ,
    {
      "title": "Good Emails Are Getting Rarer",
      "content": "I now assume you didn’t write the email by yourself. It will be harder than ever to earn the courtesy of a reply from your recipient. The longer your email, the more surface area it exposes to a human brain\u0026rsquo;s bot detection. Therefore, what you write in your first email is critically important.\nIf you are writing to a human, write like one.\nCold emails written by bots quote generic lines from your webpage. They lean on HTML with heavy pill badges. They also force connections between their pitch and your own pages. They are not generic emails, but a failed attempt at personalisation.\nLong emails are a waste of time. For the writer as well as for the reader. The goal is to communicate your idea with as few words as possible. Two-paragraph emails are ideal. Keep both paragraphs under three sentences. In the first paragraph, talk about what interests your recipient. In the second, what you want to share or discuss with them.\nThe most sinister act is to spam them. It\u0026rsquo;s the speediest way to lose trust. The other drawback is that your emails will become harder to get through. If you\u0026rsquo;re unintentionally doing it, just pause and ask yourself. If you received this email with your busy schedule, would it add value? Information overload is a reality. Being concise and valuable is the most helpful thing you can do.\nDoes that mean long emails are completely useless? Yes. I do read long emails sometimes, but most of them now seem to be written by bots. If you think you can trick people, you\u0026rsquo;re wrong. Spotting slop is not rocket science and humans are inherently good at finding patterns. These patterns are easy to detect. If you didn\u0026rsquo;t write the email yourself, you didn\u0026rsquo;t make it detection-proof either. The sooner you realise this charade isn\u0026rsquo;t worth playing, the better writer you\u0026rsquo;ll become by doing the work yourself.\nI understand that when a security researcher needs to disclose a vulnerability, it has to go through a private channel like email and must contain all the details to reproduce the flaw. In this case, email is the usual format, but any private channel could have done this communication. But I wouldn\u0026rsquo;t call it the canonical way to use email. It\u0026rsquo;s just the format everyone happened to settle on, because security flaws are older than the internet, so email took precedence.\nAll communication around email has gone through quite a few phases. One thing that sticks as wisdom: writing less is more.\n",
      "date": "2026-06-21",
      "permalink": "https://iaziz786.com/blog/good-emails-are-getting-rarer/",
      "tags": ["writing","email","communication"]
    }
    
    ,
    {
      "title": "Engineers Are Too Far From Users",
      "content": "Yesterday, I was on a phone call with a friend of mine. We were talking about our businesses and how we want to avoid doing sales. Now, he is and I too at a stage where we need to do cold calling, we need to reach out to the user, we have to talk to the user to actually start understanding from them what works, what are their requirements, things like that. I understand this should be the first thing we should be doing. We make the most common mistake \u0026ndash; not talking to the users first.\nNow, we both are software developers, and sales is definitely not our forte. We both laughed at our hesitation and the lack of experience in this field. We were tossing the ideas what we can do to actually not to talk to the users, jokingly, but we as an engineer\u0026hellip; I then realise, have been kept away from the user so much that it\u0026rsquo;s now our uncomfortable territory. I honestly do not understand how a team that serve users come to this situation where we interact users so rarely. This job primarily belongs to the sales team, the product team, and in some cases, the customer support team. But this is really weird that the engineers are kept away from talking to the people who use their product. Because I have seen engineers giving great idea because the builders really understand the capabilities of their system.\nThe company that I\u0026rsquo;m building, I will not make it so that engineers sits away from the users. I think this should be one of the topmost priority and this is one of the things I will be looking in our future engineers who are open to talk to the users. This hesitation at the organization level should not persist. There are certain kind of hierarchy as we grow will be formed for sure, but I promise that hierarchy won\u0026rsquo;t come in the way of we being close to the user. It should be the part of their job description to talking at least once a week with our users. The objective would be to actually understand their behavior very well, their pain points very well, and what they are trying to do eventually.\nNow, until that happens, I\u0026rsquo;m still at the phase where I\u0026rsquo;m early at talking to the users, and that hesitation and that reluctance is still there. Dropping that email, not getting anything in reply, that usually I\u0026rsquo;m not so much used to. Most of the days, I have been in the side where someone sells to me. But now the tables have turned. I am the one who now reach out to the people, and I need to find a good way to do this sales part. I think eventually, if I can make it fun in a way where I can find it intriguing to drop emails, find it exciting to tell about the product, I think that is when the habit will start to form. But obviously, a big part of the sale is facing the rejection.\nIt is never fun to face any kind of rejections. In our entirety of life, we do understand as human, as people, rejection hurts. As a first time founder, I need to wrap my head around it because it\u0026rsquo;s gonna happen quite a lot. So the next question I ask, how to make rejection a good thing in general, while also being a little persistent in selling the idea or selling the product? There might be two kind of rejections, I think. First kind of rejection where I am targeting the wrong customer entirely. I think these kind of rejections will be easy to maneuver because feedback will be polarising. But the next kind of rejection, where I can see the user can be a potential client, and the sheer amount of hard work required for them to get offboard of their existing solution and start using ours is something that requires a good amount of energy in general.\nIf I have to make rejections a bit fun, first, I\u0026rsquo;ll try to communicate so that I get early feedback quickly. It\u0026rsquo;s filtering out the wrong audience. The next sort of people are the interesting ones. They can become my clients because they use an existing tool for which I\u0026rsquo;m building a better version of it. If your product isn\u0026rsquo;t better I think you will be in a very bad place. In order to tell if your product is better or not, you need to start demoing. If you have talked to the users early the demo most likely provide some good value to the audience. If you have not, then be open minded to change quite a lot of things in your product.\nRejection is fun only if you are open-minded to change.\nOne more good thing about rejections that they are feedbacks. I\u0026rsquo;m also a big believer of feedback. And thinking it in terms of this will be really helpful for me. Another thing that will likely help me is to gamify this experience. I don\u0026rsquo;t know how people in sales do it currently but gamers do face this quite a lot. If the cost of doing something is almost negligible then we do it repeatedly even if the feedback is likely not in your favour. At this point, sales looks like grunt work and I need to find ways to remove as much as toil for me.\nI\u0026rsquo;m not sure if I\u0026rsquo;m going to be able to do this but at least I can make it fun.\n",
      "date": "2026-06-15",
      "permalink": "https://iaziz786.com/blog/engineers-are-too-far-from-users/",
      "tags": ["software engineering","product","communication","empathy"]
    }
    
    ,
    {
      "title": "Deliver Value, Not Implementation",
      "content": "You add an extra spoonful of sugar to your tea. It was already sweet. But the habit is so ingrained you don\u0026rsquo;t think about it. You just do it. Later you taste it and realize it was too much.\nSoftware engineers do this with code. A problem shows up. They search for existing solutions and find a few. But reading the documentation of something new is uncomfortable. Learning someone else\u0026rsquo;s API, understanding their conventions, figuring out the edge cases - it all takes effort. The unfamiliar friction makes the existing tool feel harder than building from scratch. So they build.\nThe value is in the problem solved, not the code written.\nAziz was setting up a new project. He needed short URLs for the links he would share. The thought came before he could stop it: I could build a URL shortener. A quick one. A database table, an API endpoint, some redirect logic. He opened the editor. The LLM helped. Code flowed. Tables were created. Endpoints responded. It felt like flying.\nLater that day, a colleague asked why he did not just use the host\u0026rsquo;s built-in redirects. Aziz checked. It was right there in the settings. A config change. Thirty seconds.\nHe stared at his screen. The database table. The API endpoint. The careful redirect logic. All that work, and the solution had been running on the server the whole time, waiting to be turned on.\nHe had done this before. A commenting system when giscus already existed. An analytics dashboard when PostHog and Plausible were free. An auth system when Auth0 and Clerk had been doing it for years. A feature flag tool when LaunchDarkly and Flagsmith were battle-tested. A deployment script when GitHub Actions handled pipelines out of the box. A CMS when WordPress and Ghost had millions of users finding the edge cases so he would not have to.\nEach time the same story. A problem shows up. Building feels productive. The code editor opens before the search engine. And weeks later, there is another project to maintain.\nThe cost of building has never been lower. An LLM can scaffold a working solution in an hour. An endpoint, a database, a UI. The gap between \u0026ldquo;I need this\u0026rdquo; and \u0026ldquo;it works\u0026rdquo; is almost nothing now. When the cost of building drops this low, the default answer to any problem becomes: build it.\nThe old question was \u0026ldquo;is this worth building?\u0026rdquo; The new question is \u0026ldquo;why wouldn\u0026rsquo;t I build this?\u0026rdquo;\nHere is the thing about Aziz. He built those things because he is curious. That is what makes him a good engineer. He wants to understand how things work, how they fit together, how they break. Curiosity drives most good engineers.\nBut curiosity also has a cost. It takes energy. Real, depletable energy that he only notices in specific moments. The midnight production issue. The weekend spent on a migration. The moment he looks at his own code and does not recognize it. Those moments remind him that every build, no matter how satisfying, is also a commitment he did not account for at the start.\nHe did not see this on that first afternoon. Nobody does. The cost is invisible at the beginning. The migrations he would need to write. The edge cases he had not considered. The feature request that turns a weekend project into a month of work.\nAn existing tool has already paid these costs. Its users found the edge cases. The documentation exists. The package is maintained by someone who thinks about that problem every day.\nThe learning curve of an existing tool is right in front of you. The learning curve of your own solution does not exist yet. You discover it as you go.\nThis is not an argument against curiosity. It is an argument for being careful about where you spend it.\nWhat Aziz learned was not to stop building. He learned to ask one question before he starts: am I building this to understand it, or because I need it to work?\nIf understanding - build. That is how you learn.\nIf existing - use what is already there. Then move on to the problems that actually need solving.\nThe best engineers do not build everything. They know what not to build. They deliver value, not implementation.\nAziz is still learning this. But he is getting better at noticing when he does not need to build. The URL shortener taught him that. He has not built one since.\n",
      "date": "2026-06-14",
      "permalink": "https://iaziz786.com/blog/deliver-value-not-implementation/",
      "tags": ["software engineering","bias","value","ai"]
    }
    
    ,
    {
      "title": "The $50/Million Token Problem With Fable 5",
      "content": "Anthropic dropped Claude Fable 5 yesterday. First Mythos-class model available to the public. Same tier that found and exploited vulnerabilities in every major operating system and browser earlier this year. 80.3% on SWE-Bench Pro, 29.3 on FrontierCode Diamond, beat Pokémon FireRed using nothing but raw screenshots.\nMost developers won\u0026rsquo;t need it.\nThe advantage is conditional Anthropic\u0026rsquo;s own words:\nThe longer and more complex the task, the larger Fable 5\u0026rsquo;s lead over our other models.\nThe lead shrinks on short tasks. The kind that make up most development work. TrueFoundry\u0026rsquo;s analysis confirms it. On shorter, well-scoped tasks, Fable 5 and Opus 4.8 are close. Opus 4.8 is the sensible default for most production traffic.\nMost development work is autocomplete a function, explain an error, draft a test, refactor a file. Opus 4.8 at half the price handles that.\nThe math Fable 5: $10 per million input tokens, $50 per million output tokens. 2x Opus 4.8.\nOne agentic call (50k input, 15k output) costs $1.25. Chain 12 of those for a real task, roughly $15. Max reasoning effort on hard FrontierCode tasks, closer to $20.\nThat\u0026rsquo;s a Stripe-class migration. 50 million lines of Ruby, refactored in a day. Not the kind of task most people hand to an AI.\nSpeed Artificial Analysis ranks Fable 5 #71 out of 152 models. 60.3 tokens per second. Fine for long tasks, slower on quick ones.\nThe reasoning-effort dial helps. Low effort, fewer tokens, faster answers. But then Fable 5 prices for Sonnet-class output.\nSafeguards Karpathy on launch day: the safeguards are \u0026ldquo;configured to be a little too trigger happy.\u0026rdquo; Anthropic says they\u0026rsquo;ll tune them.\nAbout 5% of sessions fall back to Opus 4.8 right now. Fable 5 prices, sometimes Opus 4.8 answers. Makes sense for security researchers and biologists. Doesn\u0026rsquo;t help with React.\nThe trial ends June 22 Fable 5 is free on Pro, Max, Team, and Enterprise plans through June 22. Then it moves to usage-based credits. Anthropic says they\u0026rsquo;ll restore it to standard subscriptions \u0026ldquo;as quickly as we can.\u0026rdquo;\nThe $20/month Pro plan crowd will stick with Opus 4.8 when the meter starts.\nWho it\u0026rsquo;s actually for Stripe compressed a two-month migration into a day. IMC aced trading-analysis evaluations across the board. Rakuten says \u0026ldquo;the extra thinking pays for itself\u0026rdquo; for autonomous operations. Anthropic\u0026rsquo;s internal team accelerated drug discovery 10x.\nEnterprises running long-horizon, multi-step workflows where the model works for hours without human intervention.\nThe benchmarks are Anthropic\u0026rsquo;s Every number comes from Anthropic\u0026rsquo;s published evals. 80.3% SWE-Bench Pro, 29.3 FrontierCode, 88.0% Terminal-Bench. Not independent tests. The starred rows for cybersecurity and biology are Mythos 5 scores. Fable 5, with safeguards active, performs closer to Opus 4.8 on those tasks.\nMarketing is cleaner than reality.\nWhere this lands Fable 5 is a specialist tool. Reach for it when Opus 4.8 has plateaued. Long-running, multi-stage, complex enough that 2x pricing is justified by 10x time savings.\nFor everything else, Opus 4.8 is half the price, faster on routine work, and doesn\u0026rsquo;t have safety classifiers tripping over security questions.\n",
      "date": "2026-06-10",
      "permalink": "https://iaziz786.com/blog/fifty-dollar-token-problem/",
      "tags": ["ai","anthropic","claude"]
    }
    
    ,
    {
      "title": "Realisation of Unfixable",
      "content": "Tell me, what’s in the world is unfixable? You will take some time to think and the answers that you come up with are the things that happens very rarely in the world. The list might contain death, passed time, environmental extinctions, entropy, etc.\nI bet the list isn’t that huge and that’s what the point I’m trying to make here.\nIf the list is this small that means you can do things dude!\nWhenever I work on things, I use to fear that what if I hit a dead end and there is no going back from there. It’s just a feeling and far from the reality. I am a software developer, I can rarely work on things that’s not fixable. The systems that we work on are infinitely malluable. That’s why tinkering and hacking is so fun. It feels like a game but it can become a reality as well. Take Apple for example, it was Wozniak’s project that has become world’s one of the most valuable company.\nThere are a few reasons why something feels unfixable. One reasons is I fear facing criticism that something that I create sucks.\nYou can spend your times on things that might not work out well for you. In this case time is a scares resources.\nIf you don’t have agency, start building and stop consuming less.\nIf you can build personal relationship with someone capable and help them convince your vision together as a team you can do that’s unthinkable. You two (or many) don’t even know what you can create if you keep open mind. I believe that you can create highly creative and inspiring things.\nThe story of Apple also brings one important epiphany. You need to learn to sell your idea to make it big. I don’t know about magic tricks but creating urgency out of thin air is fascinating. In order to do this you need to show people what they can’t see. This is why storytelling is important. Remember the phase “show, never tell”?\n",
      "date": "2026-06-09",
      "permalink": "https://iaziz786.com/blog/realisation-of-unfixable/",
      "tags": []
    }
    
    ,
    {
      "title": "Your Next Idea Isn't in Your Head, It's in Your Browser Tabs",
      "content": "I’m going to show you how to find great ideas, the kind that are already hiding in plain sight, right next to you.\nI struggle with ideas. Especially good ones. And I know I’m not the only one who wakes up thinking:\n“What should I work on?”\nAfter thinking about this a lot, I realized something simple:\nAn idea is just a solution to a problem.\nSo instead of chasing ideas, start noticing problems.\nHere\u0026rsquo;s a simple system that worked surprisingly well for me.\nA Tab at a Time Look at your browser right now.\nToo many tabs open?\nGood.\nPick any one of them and ask yourself:\nHow can I do what I’m supposed to do here faster and more accurately?\nThis one question is powerful. When I started doing this, my idea list didn’t just grow, it exploded.\nCapture the End Goal Don’t get stuck in what people are doing. Focus on what they’re trying to achieve.\nFor example:\nGmail: People are trying to figure out what to do next Slack: Teams want alignment and clarity on execution OTPs: How to verify human identity Phone: What needs my immediate attention It’s not about the tool. It’s about the intent.\nGroup Them Now take it a step further.\nGroup similar tabs together.\nSame type of tools, same workflows, same purpose.\nThen ask the same question again.\nYou’ll start noticing patterns and more importantly, gaps.\nYour goal here is simple:\nExtract common problems.\nAnd trust me, there are always more than you expect.\nListen to What People Are Saying Every product has a community.\nForums, Reddit, Discord, Twitter, people are constantly talking.\nComplaining. Suggesting. Struggling.\nIf you want to move faster, use LLMs to scrape and summarize these conversations. You’ll save hours and uncover insights you would probably miss manually.\nWhat to Actually Build (Filters) Having ideas is easy. Choosing the right one is hard.\nHere’s how to filter them:\nIs There New Tech Unlocking This? Ask yourself:\n“Is something now possible that wasn’t possible before?”\nThat’s where big opportunities live.\nAI is a perfect example, but don’t force it everywhere.\nNot every problem needs AI. Pick the right tool for the job.\nCan You Actually Finish It? Let’s be honest.\nMost projects don’t get finished.\nThe ratio is heavily skewed.\nSo be picky.\nDon’t jump randomly between ideas. And on low motivation days?\nDo the smallest thing possible.\nEven fixing a typo counts.\nDoes It Connect With a Community? Building for a community changes everything.\nIt gives you feedback, motivation, and direction.\nFor me, that’s cloud and self hosting. That’s what drives me and led me starting my company.\nIf you want better ideas:\nStop just browsing. Start engaging.\nTalk to people. Observe them. Understand them.\nThe easier it is to interact with your audience, the more valuable insights you will get.\nFinal Thought Good ideas aren’t rare.\nThey’re just overlooked.\nThey’re sitting in your tabs, your tools, your daily frustrations.\nAll you have to do is pay attention.\nI hope you enjoy this process as much as I did.\nIf you try it, I would genuinely love to hear what you discover.\n",
      "date": "2026-04-28",
      "permalink": "https://iaziz786.com/blog/your-next-idea-isnt-in-your-head-its-in-your-browser-tabs/",
      "tags": ["idea","startup","community","tab"]
    }
    
    ,
    {
      "title": "Why Urgency Is Your Friend",
      "content": "I used to be confused about why urgency is so important in founders. Why would you execute like you’re going to die tomorrow?\nI think it’s linked to human behaviour and how we choose to pick and work on something.\nSee, we all have dreams; many of us dare to execute upon those dreams. I am not aware of the exact percentage, but I believe it’s somewhere between 40–50%. At least some effort is made. It’s a good number, and it is great to see when people struggle for it. What I want to highlight is the next step: how many keep working on those dreams constantly? I think the number won\u0026rsquo;t even be in the single digits. It will be in decimal points that start with zero.\nThere are two things that make this number such a drastic difference: either you lack feedback with right dopamine, or the idea—which feels novel and exciting at first—stops feeling that way. I won’t give you advice on how to get encouraging feedback, but here’s what you can do when an idea strikes you: stop everything and just work on it. Notice that time is your enemy here. If you let it hang, you are basically letting it die.\nInspiration is perishable.\nThere is another way to let your idea grow which is more long-term: having a belief so strong that it drives you by itself. To reach this point, you need to school yourself well. This foundation must be built on strong data. It must be so strong that it almost feels like a delusion to others, but it definitely isn’t.\nIt’s okay if the initial foundation isn\u0026rsquo;t strong regarding your new spark. But it needs to polarise, either into flames or ashes; the sooner the better. If it becomes a flame, all it requires is your energy and discipline.\nThe rest will be an amazing journey.\n",
      "date": "2025-12-17",
      "permalink": "https://iaziz786.com/blog/why-urgency-is-your-friend/",
      "tags": ["urgency","inspiration","effort","discipline"]
    }
    
    ,
    {
      "title": "Keep Working On Wrong Ideas",
      "content": "It’s important to ask what you should be working on. But since most side projects are abandoned — is that even the right question to start with?\nIf you’re not pushing your work beyond the finish line, how do you know whether it’s good or bad? The excitement fades away, and you start questioning — is this a wrong idea?\nI want to tell you — you should keep working on your wrong ideas.\nBut why!? I don’t know — maybe I’m an idiot. An idiot who knows he’s not going to create something new or revolutionary.\nBut I enjoy the process of creating software. The age of AI has only fueled that passion further.\nNow, I can clone a great open-source library, and within a few minutes of clauding gives me gold.\nI love recreating projects to understand what’s going on in the creator’s mind — why they made certain trade-offs, and why some approaches won’t have worked if I were building it myself. Those “aha” moments are addictive.\nMy point is: now there’s one less reason to quit. If you get stuck, you can easily look at others’ implementations and get unstuck.\nPreviously, it used to be so hard to even understand how a project was structured. Now, it’s a piece of cake.\nIf you’re curious and know how to use AI well, you can sit for hours and watch your project take shape — something that used to take ages and kill your flow.\nWhat is a wrong idea? You tell me. I won’t judge, and neither should others.\nWithout hard work, there are no wrong ideas.\nThe good “wrong ideas” are the ones you discover, not the ones you ruminate on.\nAnd you discover them through the sheer amount of hard work you put in. You can’t just come on day 4 and decide it isn’t worth it\nOver emphesize it If you’re a builder, overemphasize the output of your work. I have made the mistake of being too rational about it — it doesn’t pay as much as overstating it.\nRemember, overemphasize doesn’t mean being blind about it. Always critique your work.\nThis is the path to developing self-belief.\nSure, some ideas will be garbage — but you should still complete them. Why miss out on the return on investment?\nThe wrong ideas teach you more than the good ones ever will.\nAnd that’s what matters the most — sustain, iterate, and be in the flow.\nBuild crapy things and iterate I don’t expect myself to create my best work on the first go. If I did, I’d be lucky — but also doubtful.\nLike this blog post itself — I know it has many flaws, but I wanted to get it out. “I’ll do it later” usually means I’ll never do it.\nThis isn’t written in stone, so I’ll keep updating it whenever I find something I don’t like.\nBut the mantra is clear:\nIt\u0026rsquo;s not crappy if you\u0026rsquo;re still rolling the dice. It\u0026rsquo;s crappy when you stop.\nThik about the antidote Who are you doing all this for? At least let it be for yourself.\nPeople might not use what you build. Build for yourself.\nMy writing might suck, and people might not read it. Write for yourself.\nIf judgment is your problem, then building for at least yourself is the solution.\n",
      "date": "2025-10-05",
      "permalink": "https://iaziz786.com/blog/keep-working-on-wrong-ideas/",
      "tags": ["self-belief","ideas","persistence"]
    }
    
    ,
    {
      "title": "Boring Work Needs Tension",
      "content": "We are all moved by great movies, cinematography, and stories. Watching them is fun because you can imagine yourself resonating with a character. You are thrilled by the tension the story creates and curious how it will be resolved.\nMany find software development a dull job where you have to write exactly what your PM or client asks for. It’s exciting at first, but it can become boring after a few iterations.\nWhatever doesn\u0026rsquo;t excite you, change it.\nWhen we, as developers, push ourselves to be protagonists, we discover many problems to solve — a lot of tension to resolve. Here are a few good problems for everyday devs:\nYour CI/CD takes a huge amount of time because you forgot to leverage caching. You forgot to add connection pooling and your service bombarded the database, causing too many open connections. You misconfigured the garbage collector and now you have a memory leak that keeps growing. If it takes you more than 3 seconds to understand what you wrote last week, it’s poorly written. Latency is high for your users in Mumbai because your servers are in Singapore. The database becomes very slow when you start dumping data in batches. You want consistent API responses for read operations for users in both Mumbai and Singapore. These are not trivial problems; they happen every day. These are our villains — irritating, unwanted, and surprising. We should eliminate them.\nPick your fight. This is one way to make your day exciting. If you can\u0026rsquo;t tackle these at work, do it in your personal projects.\nIf you chase the right tension, a story will follow.\n",
      "date": "2025-09-14",
      "permalink": "https://iaziz786.com/blog/boring-work-needs-tension/",
      "tags": ["software-development","work","tension"]
    }
    
    ,
    {
      "title": "OOP is not Design Patterns",
      "content": "The OO concepts like inheritance, polymorphism, etc. they only provide you the building blocks. They don’t provide you with the ways of structuring your code. The design patterns are good at this. Not always, but certainly can help.\nUsing design patterns you develop a common language with your stakeholders. Instead of lengthy explanation, you just provide a name which immediately clicks to their mind.\nYour language might not support all OO concepts. Take Go as an example, It doesn’t support inheritance. Does this means you can’t build reusable components, flexible schema, and maintainable code? You surely can! So main take away from here would be you build on top of design patterns even if you don’t have all OO elements.\nYou as a junior developer, you need to know that not re-inventing a lot wheels will give you leverage. You as senior engineer has responsibility that your less experienced mates are not discovering what’s already discovered. That will be a wasteful experiment.\nBesides there are many criticism for the design patterns altogether. I know they are not an ideal choice. I can suggest you shouldn’t force them as defaults. The patterns means repetition and using them is art. Your brains has to click and it will do it only when you have done it many times.\nSo I guess the initial hurdle is how to come out of that initial threshold?\n",
      "date": "2025-08-08",
      "permalink": "https://iaziz786.com/blog/oop-is-not-design-patterns/",
      "tags": ["design-patterns","oop"]
    }
    
    ,
    {
      "title": "Self-hosted: WireGuard VPN Server on Ubuntu, with MacOS and Android Clients",
      "content": "WireGuard is a modern, high-performance VPN designed to be easy to use while providing robust security. This guide will walk you through the steps to set up a WireGuard VPN server on Ubuntu, and connect to it using MacOS and Android clients.\nSetting up the WireGuard VPN Server Install WireGuard on your Ubuntu server:\nsudo add-apt-repository ppa:wireguard/wireguard sudo apt-get update sudo apt-get install wireguard Generate the server keys:\numask 077 wg genkey | tee /etc/wireguard/privatekey | wg pubkey \u0026gt; /etc/wireguard/publickey Configure the VPN in /etc/wireguard/wg0.conf:\n[Interface] Address = 10.0.0.1/24 ListenPort = 51820 # standard port, change as you like PrivateKey = (your server\u0026#39;s private key) PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE Enable and start the VPN:\nsudo systemctl enable wg-quick@wg0 sudo systemctl start wg-quick@wg0 Configuring Firewall (optional): If your firewall blocks all ports by default you have to allow UDP connections on port 51820 as WireGuard uses UDP for its transport protocol.\nIf you use ufw use the following commands.\nsudo ufw allow 51820/udp Remember to enable the firewall if it\u0026rsquo;s not already enabled:\nsudo ufw enable Connecting a MacOS Client Install WireGuard on your MacOS device. You can do this through the App Store. Also, make sure that you have wireguard CLI install. You can do that by running homebrew command. brew install wireguard-tools Generate the client keys in terminal:\nwg genkey | tee privatekey | wg pubkey \u0026gt; publickey Add the client\u0026rsquo;s public key to the server\u0026rsquo;s configuration:\n[Peer] PublicKey = (your client\u0026#39;s public key) AllowedIPs = 10.0.0.2/32 Restart the WireGuard service to apply the changes:\nsudo systemctl restart wg-quick@wg0 Create the client configuration in WireGuard on MacOS:\n[Interface] PrivateKey = (your client\u0026#39;s private key) Address = 10.0.0.2/32 DNS = 10.0.0.1 [Peer] PublicKey = (your server\u0026#39;s public key) Endpoint = (your server\u0026#39;s IP):51820 AllowedIPs = 0.0.0.0/0 Connecting an Android Client Install the WireGuard app: Open the Google Play Store on your Android device, search for WireGuard, and install the WireGuard app.\nGenerate a key pair: Open the WireGuard app and tap the \u0026ldquo;+\u0026rdquo; button to add a new tunnel. Select \u0026ldquo;Create from scratch.\u0026rdquo; This will create a new key pair for your Android client.\nConfigure the tunnel: In the new tunnel configuration:\nName your tunnel. This can be anything you like. It\u0026rsquo;s just to identify the connection in your WireGuard app. The Private key should be automatically generated. Tap on the eye icon to view the key and the corresponding Public key. You\u0026rsquo;ll need to add this Public key to your server\u0026rsquo;s configuration later. For Addresses, enter the next IP address in your VPN\u0026rsquo;s subnet. For example, if your server is 10.0.0.1 and your macOS client is 10.0.0.2, you could use 10.0.0.3/32 for your Android client. Leave DNS servers empty for now. Under Peer, you\u0026rsquo;ll need to add the Public key of your server, the Endpoint (your server\u0026rsquo;s public IP address and the port WireGuard is listening on), and the Allowed IPs. For Allowed IPs, you can use 0.0.0.0/0 to route all traffic through the VPN, or use your VPN\u0026rsquo;s subnet (10.0.0.0/24 in this example) to only route internal VPN traffic. Add the Android client to the server\u0026rsquo;s configuration: On your server, open the WireGuard configuration file (/etc/wireguard/wg0.conf), and add a new [Peer] section for the Android client. It should look something like this:\n[Peer] PublicKey = ANDROID_PUBLIC_KEY AllowedIPs = 10.0.0.3/32 Replace \u0026ldquo;ANDROID_PUBLIC_KEY\u0026rdquo; with the Public key you generated on your Android device. Save the file and exit, then restart the WireGuard service to apply the changes:\nsudo systemctl restart wg-quick@wg0 Connect: Back on your Android device, you can now tap the toggle switch to connect to the VPN. If everything is configured correctly, it should connect successfully. You can verify your connection by checking your IP address (it should be your server\u0026rsquo;s IP address if you\u0026rsquo;re routing all traffic through the VPN), or by trying to access a resource on your VPN\u0026rsquo;s network.\nSpeed Differences Depending upon the various factors you speed might vary with the VPN. Let\u0026rsquo;s see how does the speed looks like for me. My VPN server is hosted in Finland and I\u0026rsquo;m using it from India so definitely there will be some latencies.\nSpeed without VPN I\u0026rsquo;m getting 197.32 Mbps download and 143.42 Mbps upload speed out of my 200 Mbps connection without any VPN in place.\nSpeed with VPN I\u0026rsquo;m getting 177.80 Mbps download and 66.52 Mbps upload speed out of my 200 Mbps connection with any VPN in place.\n👋🏼\n",
      "date": "2023-05-25",
      "permalink": "https://iaziz786.com/blog/self-hosted-vpn-wireguard/",
      "tags": ["vpn","wireguard","hetzner","android","macos","ubuntu"]
    }
    
    ,
    {
      "title": "Work Like a CPU",
      "content": "A CPU is one of the best creations of mankind. It helps you do tasks at an unmatched speed. It is a complicated piece of hardware but at its core, it does four things:\nfetch - the instruction from the RAM. decode - the fetched instruction to the actual action it needs to perform. execute - the decoded instruction. store - the execution results for future use. A modern CPU can do this billions of times in a second.\nThis makes the CPU a very focused piece of technology. You have just to tell it to get this done and it will get it done. Period.\nCollect \u0026ndash; Your Instructions If you don\u0026rsquo;t know what you are going to achieve that day, how can you identify what is causing the blocker for it?\nClarity in life is bliss.\nTherefore it is extremely important before you start a day you should have the tasks prepared. There is no retrospection if don\u0026rsquo;t know what you were supposed to do.\nWhatever works for you, on paper or digital format, a todo-list or a calendar event, always know your tasks.\nIn the collect phase, you might need to research before you start executing. And researching can also be a task in itself. Focused research will require you to shut off from others.\nShut Off \u0026ndash; Focus Execution Once you got the clarity about the tasks at hand it\u0026rsquo;s time to lose yourself in the execution.\nIn your mind always think about the next steps that you need to do. Keep executing those tasks. One after another. Just like the \u0026ldquo;fetch-decode-execute\u0026rdquo; of the CPU you are in a constant loop of execution.\nAt times you might lose focus, maybe you start thinking about that new phone that just got launched or someone has pinged you. RESIST these aberrations!\nDespise \u0026ndash; Context Switches When a CPU does context switches it has to wait, and while it happens it doesn\u0026rsquo;t do anything. The precious CPU time (cycles) gets lost doing nothing.\nThis is true for humans as well. When your context switch, you shift your attention, and you lose your train of thought. This can increase the chances of:\nmaking mistakes decrease productivity have mental fatigue longer completion time, hence increasing stress. We can do multitask but we are not good at it.\nShifting \u0026ndash; Gears of Focus Whatever you do you can\u0026rsquo;t completely avoid context switching.\nSync-ups might be inevitable, discussions might be necessary and follow-ups might be required. When you do these at least prepare your brains that it\u0026rsquo;s going to happen. Have a dedicated time frame in which you won\u0026rsquo;t go too deep into your tasks.\nKeep thing things loose.\nConclusion Focusing on your work is one of the most important things. You should have time slices in which you work in full dedicated mode and loose mode. Don\u0026rsquo;t mix both of them.\nIn the dedicated mode keep executing your tasks one by one just like a CPU does. But also keep a dedicated time for context switching like meetings and follow-ups and do those in only those time frames.\n",
      "date": "2023-05-11",
      "permalink": "https://iaziz786.com/blog/work-like-a-cpu/",
      "tags": ["cpu","productivity","focus"]
    }
    
    ,
    {
      "title": "Unleash Your Potential As a Brand",
      "content": "Who are you?\nYou might state your profession to answer this.\nI argue, to answer this, consider yourself as a brand.\nWhy branding yourself is important? Brand value is the top priority for an organization. They are very sensitive about it. It is important because it creates trust. No one will transact with a company on which they don\u0026rsquo;t trust.\nBut It isn\u0026rsquo;t limited to organizations only.\nYou too are trustworthy because of your brand.\nYou don\u0026rsquo;t care to think, but, your actions are getting monitored by everyone you interact with. You do it too, hence as humans, they also create an image of yourself based on your behavior in each situation.\nThey associate your name with few bullet point about yourself in their mind.\nThis all may look like I\u0026rsquo;m telling you to be a people pleaser, right?\nNo, You should never do that!\nHow to become a brand without being a people pleaser? You need to have ethics before you start creating a brand. You cannot sail to the right destination without having the correct map.\nYou are result of your ethics and your honesty towards them.\nWhen you have ethics, you dictate what people think about yourself. Again, it\u0026rsquo;s less about others\u0026rsquo; perception and more about taking control.\nIt is natural to occasionally falter in upholding your ethics, but it is crucial to learn from these instances and make necessary adjustments. It\u0026rsquo;s not because what others will think about you, but you cannot let down the most important person on earth \u0026ndash; yourself.\nI can let down thousands of people and I don\u0026rsquo;t care. But letting down the \u0026ldquo;I\u0026rdquo; is my biggest nightmare.\nHow to create ethics? Imagine you are on a stage, going to give a presentation about a product. The product is something you have been working for the last two and a half decades or your life. This is the most important presentation of your life because the product is you.\nYour ethics should drive the presentation for you.\nWe have found many ways to deliver great products. But we have hardly found many ways to deliver a great self.\nIt will look like this for me:\nLadies and gentleman, today I\u0026rsquo;m launching [MY NAME]:\nI am very competitive. I don\u0026rsquo;t believe in mediocrity. Specially in things I am passionate about. I follow \u0026ldquo;If you love something, become immersed in it\u0026rdquo; kind of mentality. As a passionate techy, I can deliver almost all the step in a software creation flow. From the development to operation with full hands on experience. I believe simplicity, quality, and faster iteration matter the most in software. I believe discipline is the most important skill. Even in my late twenties am delighted to tell you, I\u0026rsquo;m the most fit version of myself. Being healthy matters to me. I prefer to live a minimalist life. \u0026ndash; My ethics\nIn future posts, I will delve deeper into my personal ethics. In the meantime, I encourage you to develop a similar list of guiding principles. Go ahead, create your ethics and share with the world today. If you commit in public, maybe that will force you to follow your ethics.\nConclusion If you follow your ethics with true honesty, you will become an impactful brand. Keep your ethics list at the top of your mind. If anything you do doesn\u0026rsquo;t align with your ethics, actively reject it.\nThe most inspiring individuals are the one who have great ethics and adhere to it until they become a brand.\n",
      "date": "2023-04-28",
      "permalink": "https://iaziz786.com/blog/branding-yourself/",
      "tags": ["brand","marketing"]
    }
    
    ,
    {
      "title": "Breaking Free: How I Self-Hosted My SMTP Server with Haraka",
      "content": "You use SMTP providers to programmatically send emails. I don\u0026rsquo;t like these when using third-party SMTP providers:\nSending emails is free, I won\u0026rsquo;t pay a penny more than what\u0026rsquo;s minimum. One small bug and you sent 10M emails. Oh no! MY MONEY!!! I\u0026rsquo;m pissed that Amazon SES rejected my request for an SMTP server. :(( I won\u0026rsquo;t know the internals\u0026ndash;I know not everyone wants to know how SMTP works, but I do! Previously I\u0026rsquo;ve used Postal, which is not simple but okay. Can I do better? Isn\u0026rsquo;t why I\u0026rsquo;m writing this?!\nI found that Zerodha uses Haraka and Karan\u0026ndash;their DevOps guy, mentioned it is easy-setup and performant.\nEnough Karan, I\u0026rsquo;m already convinced. Let\u0026rsquo;s do this!!\nSo I tried. I must say, it\u0026rsquo;s darn simple!\nBefore that, do you know\u0026hellip;\n📧 The emails are sent on outbound port 25 \u0026amp; 465 and they are blocked by default? Get ready for an email adventure! Imagine sending an email from you@example.com to myfriend@gmail.com. By default, your server sends the email to port 25 or 465 of the receiver\u0026rsquo;s email server. It\u0026rsquo;s like a secret handshake between email servers, figuring out the correct address for gmail.com before delivering your message.\nBut what if you want to host your own SMTP server to send those emails? Buckle up, because we\u0026rsquo;re diving into the world of cloud providers! I\u0026rsquo;ve been using Hetzner, a fantastic value-for-money option. Now, most cloud providers are like overprotective parents – they block outbound ports 25 \u0026amp; 465 to prevent spamming.\nNo worries, though! With Hetzner, it\u0026rsquo;s like joining an exclusive club. After you pay your first bill, all you need to do is raise a ticket request, and they\u0026rsquo;ll unblock those ports for you, just like that. It\u0026rsquo;s like having the bouncer let you into the coolest party in town.\nSo, gear up to host your SMTP server and send emails with freedom and style!\nDNS Setup You need to DNS configuration to send the emails. The MX record should point to the IP of your server. When you send mail to example.com, the MX record is obtained. Wherever the MX records point it will eventually resolve to an IP address.\nThat IP is used to send the mail on either port 25 or 465. I used ChatGPT-4 to explain you about MX record \u0026amp; SPF.\nHow do you set up an MX record? An MX (Mail Exchange) record is a type of DNS record that specifies the mail servers responsible for receiving emails on behalf of your domain. To set up an MX record, follow these steps:\nLog in to your domain registrar or DNS hosting provider\u0026rsquo;s control panel.\nNavigate to the DNS management section.\nCreate a new MX record with the following details:\nName/Host: Leave this field empty, \u0026ldquo;@\u0026rdquo; or enter your domain name, depending on the requirements of your DNS provider. This ensures that the MX record is added to the root level of your domain (e.g., example.com). Type: Select \u0026ldquo;MX\u0026rdquo; as the record type. Value: Enter the fully qualified domain name (FQDN) of your mail server. For example, \u0026ldquo;mail.example.com\u0026rdquo;. Priority: Assign a priority to the mail server. Lower numbers have higher priority. If you have multiple mail servers, the receiving server will attempt to deliver the email to the one with the highest priority first, and then move on to the others in case of failure. Save the MX record: Click on the \u0026ldquo;Save\u0026rdquo; or \u0026ldquo;Add Record\u0026rdquo; button to save the new MX record. The DNS changes may take some time to propagate.\nHere\u0026rsquo;s an example of an MX record configuration:\nName/Host: @ (or your domain name) Type: MX Value: mail.example.com Priority: 10 If you have multiple mail servers, you can add additional MX records with different priorities. For example:\nName/Host: @ (or your domain name) Type: MX Value: backupmail.example.com Priority: 20 In this case, the receiving server would try to deliver emails to \u0026ldquo;mail.example.com\u0026rdquo; first, and if that fails, it would attempt delivery to \u0026ldquo;backupmail.example.com\u0026rdquo;.\nAfter setting up your MX record, your domain will be able to receive emails through the specified mail servers. Ensure that your mail servers are properly configured to accept emails for your domain and deliver them to the appropriate mailboxes.\n\u0026ndash; by ChatGPT\nAt this point, it should be enough to add the MX record but we should tackle email spoofing and phishing as well. You require SPF for that. It\u0026rsquo;s one of many methods to prevent those.\nWhat is SPF? Sender Policy Framework (SPF) is an email authentication protocol designed to prevent email spoofing and phishing attacks by verifying that an email message is sent from an authorized mail server.\nHere\u0026rsquo;s how SPF helps prevent email spoofing and phishing attacks:\nDomain owner publishes an SPF record: The domain owner creates an SPF record in their domain\u0026rsquo;s DNS settings. This record lists all the authorized mail servers (IP addresses or hostnames) that are permitted to send emails on behalf of the domain.\nEmail is sent from a mail server: When a mail server sends an email on behalf of the domain, the email includes the sender\u0026rsquo;s domain and the IP address of the sending server in the email header.\nReceiving mail server checks SPF record: When the receiving mail server gets the email, it checks the sender\u0026rsquo;s domain for an SPF record. If the SPF record exists, the receiving server compares the sending server\u0026rsquo;s IP address or hostname against the authorized mail servers listed in the SPF record.\nSPF validation result: There are three possible outcomes of the SPF validation:\nPass: The sending server\u0026rsquo;s IP address or hostname matches an authorized server in the SPF record. The receiving server accepts the email, and it is less likely to be flagged as spam or phishing. Fail: The sending server\u0026rsquo;s IP address or hostname does not match any authorized server in the SPF record. This suggests that the email could be a spoof or phishing attempt. The receiving server may reject the email, flag it as spam, or apply additional scrutiny. Neutral or other results: In some cases, the SPF record may be misconfigured or not definitive. In these cases, the receiving server may apply other mechanisms to determine the legitimacy of the email, such as DKIM (DomainKeys Identified Mail) and DMARC (Domain-based Message Authentication, Reporting, and Conformance). By setting up an SPF record, domain owners can help protect their domain from being used in email spoofing and phishing attacks. This makes it more difficult for attackers to impersonate a legitimate domain, ultimately reducing the effectiveness of these types of attacks.\n\u0026ndash; by ChatGPT\nHow to add SPF to DNS record? To add an SPF record to your domain\u0026rsquo;s DNS settings, follow these steps:\nLog in to your domain registrar or DNS hosting provider\u0026rsquo;s control panel.\nNavigate to the DNS management section.\nCreate a new TXT record with the following details:\nName/Host: Leave this field empty, \u0026ldquo;@\u0026rdquo; or enter your domain name, depending on the requirements of your DNS provider. This ensures that the SPF record is added to the root level of your domain (e.g., example.com). Type: Select \u0026ldquo;TXT\u0026rdquo; as the record type. Value: Add the SPF record value. The value should start with \u0026ldquo;v=spf1\u0026rdquo; and list the authorized mail servers or IP addresses, followed by an action for unauthorized servers. Here\u0026rsquo;s an example of an SPF record value:\nv=spf1 ip4:192.0.2.0/24 ip4:198.51.100.0/24 include:_spf.example.net -all This SPF record value has the following components:\nv=spf1: This indicates the SPF version being used, which is version 1. ip4:192.0.2.0/24: This authorizes the IP addresses in the range 192.0.2.0 to 192.0.2.255 to send emails on behalf of the domain. ip4:198.51.100.0/24: This authorizes the IP addresses in the range 198.51.100.0 to 198.51.100.255 to send emails on behalf of the domain. include:_spf.example.net: This includes the SPF record of another domain (example.net) and authorizes its mail servers to send emails on behalf of your domain. This is useful when using third-party email services. -all: This indicates that any mail server not listed in the SPF record is not authorized to send emails on behalf of your domain. The receiving server should mark such emails as a hard fail. If you want a soft fail, use ~all instead. Save the TXT record: Click on the \u0026ldquo;Save\u0026rdquo; or \u0026ldquo;Add Record\u0026rdquo; button to save the new SPF record. The DNS changes may take some time to propagate. Once you have added the SPF record to your domain\u0026rsquo;s DNS settings, receiving mail servers will check it when they receive emails from your domain. This helps protect your domain from email spoofing and phishing attacks by verifying that emails are sent from authorized servers.\nRemember to update your SPF record whenever you add or remove mail servers or third-party email services that send emails on behalf of your domain.\n\u0026ndash; by ChatGPT\nThis will be enough for the DNS related changes. We can move ahead with the Haraka setup now.\nSetup Haraka 1. Installation It\u0026rsquo;s a CLI tool and you can install it with NPM.\nsudo npm install -g Haraka Now you can use the haraka from your CLI. Next, create a folder which Haraka will use to start the server.\n2. Folder \u0026amp; Files The setup starts here. At first, Haraka needs a folder where it holds all files it requires.\nharaka -i /var/local/your-smtp-folder In Haraka\u0026rsquo;s lingo, it is called creating the service. It gives you a few files and folders to work with. We need to tweak a few of them to work for our domain.\nIf your email address is you@example.com you need to put your example.com to the config/host_list file. Just put your domain name in plain text, simple as that.\nYou can put a subdomain as well. I like the mail domain as mailer.example.com.\n3. You Need Plugins Haraka uses plugins do to almost everything. Hence, to send emails you also need plugins. We need two plugins for now:\ntls \u0026ndash; Haraka uses port 587 to send mails. It is like port 443 of HTTP. Therefore it requires TLS for security. auth/flat_file \u0026ndash; This is for user credentials management. You shouldn\u0026rsquo;t use it in production instead use auth-enc plugin. 3.a. TLS Setup I won\u0026rsquo;t go too deep into this topic but the steps below will help.\nI\u0026rsquo;ve used ZeroSSL because they\u0026rsquo;re free and simple. You\u0026rsquo;ve to rotate the certificates every 90 days though. But there is a way to automate it.\nEventually, you will have three files, ca_bundle.crt, certificate.crt, and private.key. You need to generate a new file combining these three files.\nThe order here is important, so follow the order of the cat command.\ncat private.key certificate.crt ca_bundle.crt \u0026gt; config/tls/example.com.pem The config folder here resides in the folder which the haraka command generated for you on step 2.\n3.b. Auth User Setup You need to create a config/auth_flat_file.ini file. Put this content inside it. Don\u0026rsquo;t forget to change testpassword with a stronger password.\n[core] methods=PLAIN,LOGIN,CRAM-MD5 [users] you@example.com=testpassword 4. Check If All Works You must be done at this point. There are lots of tools to check SMTP. I\u0026rsquo;m going to use swaks.\nswaks --tls --to myfriend@gmail.com --from you@example.com --server example.com --port 587 --auth-user you@example.com --auth-password testpassword This command sends a test mail to myfriend@gmail.com from you@example.com using example.com on secure port 587 using you@example.com\u0026rsquo;s credentials with password testpassword.\nHere is a service file which you can use with systemd for the Haraka process management.\n[Unit] Description=Running Haraka mail servers After=network.target Wants=network-online.target [Service] Restart=always Type=simple ExecStart=/usr/bin/sudo /usr/bin/haraka -c /var/local/your-smtp-folder [Install] WantedBy=multi-user.target Change the /var/local/your-smtp-folder to the location where you\u0026rsquo;ve created the Haraka service.\nConclusion At the start I mentioned setting up an SMTP server is darn simple. Maybe you might find it a little intimidating. I understand you. I\u0026rsquo;m a nerd who wants to know the internals. You might not. Feel free to use whatever is your preference. Easy or a more hands-on setup like this post. I wrote this for my future self and also for people who like to get intimidated. Who push to understand the systems they work with.\nAnd for those who do, you will find that setting up this may require only one hour. In my case the only time taking process was to wait to unblock port 25 \u0026amp; 465 from Hetzner. Once it had, everything flows smoothly.\nIf you face any issue and wants to talk to me, just hit me up on Twitter.\nTwitter: iAziz786\n",
      "date": "2023-04-24",
      "permalink": "https://iaziz786.com/blog/self-hosted-smtp-haraka/",
      "tags": ["smtp","haraka","mail","email","smtp","hetzner"]
    }
    
    ,
    {
      "title": "Small Simple Solutions Scale",
      "content": "What kills a developer\u0026rsquo;s productivity? Over engineering, for sure.\nYou read tech blogs from companies which are massively bigger than you. And make technical decisions trying to understand copy their style and architecture.\nYou are missing the point!\nA good presentation is like a good story to be told. A story in which they fight an obstacle. Most people think that the same obstacle is going to bite them in future.\nAnd a good presenter stated that this decision has \u0026ldquo;worked well for us\u0026rdquo;. It means that it will not be fit for everybody but they have happened to benefit from it.\nA good engineering team start lean and simple to their current architecture. And that should be the goal of any technical decision.\nHave your own story to tell If you go and ask any good company what made them successful (depends on your definition) they will never say because we copied that other company.\nInstead most of the time they will have their unique recipe.\nIt will be very hard to have your distinctive path without starting simple.\nWhen you hit any roadblock with this approach at least it will be satisfying to know that the simplest solutions don\u0026rsquo;t work. Even in that situation though, you should look for a solution which is again simple.\nI am sure if you start with this, pretty soon you will have your unique tech stack or maybe not so unique, which can scale easily to serve your needs.\nCase Study Let\u0026rsquo;s keep the name of the company till the end. But in 2016 they were serving this:\n42 Billion messages / day 1.6 Billion pictures / day 250 million videos / day They must have grown since then.\nTheir tech stack looks like this.\nErlang (Programming Language) FreeBSD (Operating System) SoftLayer (Hosting) If you see their tech stack is a little unconventional. And this is what I am trying to say through this blog. Don\u0026rsquo;t pick things because some shining-looking company have done it. Do what is right for you. And to find what is right for you, start simple!\nThe company is WhatsApp by the way.\nReference https://developers.facebook.com/videos/f8-2016/a-look-at-whatsapp-engineering-for-success-at-scale/\n\u0026ndash;\n",
      "date": "2022-10-02",
      "permalink": "https://iaziz786.com/blog/small-simple-solutions-scale/",
      "tags": ["scale","software engineering","whatsapp"]
    }
    
    ,
    {
      "title": "How to Get a Free PostgreSQL* Database?",
      "content": "Sign Up to Cockroachlabs Cloud Go to the cockroachlabs.com and create your account.\nCreate a Cluster on their Cloud After successfully login you will see an option to create the cluster.\nClick on the Create Cluster. Select Serverless on the plan section. Configure other options like Cloud provider, Regions, Spend limit, and the Cluster name as you like. Next, click on the Create your free cluster. You get a cluster with 5 GB of storage space. It is ~10x more than the offering from MongoDB Atlas.\nCreate the DB User After the cluster creation it will ask you to create the user. Enter the username you like and generate the password for that user.\nCopy the generated password for future use.\nGet the Connection String Now that your are ready to connect to the database, click on the Connect button for the connection URL. It will have the postgresql dialect and all the other details except the password which you have copied from the previous step.\nThere you have it! A PostgreSQL* cluster on cloud for free.\n*Does CockroachDB supports all the features of PostgreSQL? No, there are few features which are not supported. Please refer to the PostgreSQL Compatibility page for more info. ",
      "date": "2022-07-02",
      "permalink": "https://iaziz786.com/blog/free-cockroachdb-server/",
      "tags": ["postgres","postgresql","cockroachdb"]
    }
    
    ,
    {
      "title": "One Step At a Time on Your Personal Projects",
      "content": "Build Tools for Daily Live I feel stuck on the personal projects that I work on. I can say with some confident that at some point you will feel or have felt the same. It just all starts with adrenaline rush which doesn\u0026rsquo;t last longer.\nIt is very important that the projects you build excites you. Otherwise you will abandon it and feel guilty again!\nOne way to keep the provocation going on is create what you need right now. Think about any mundane work and if you can automate it through coding just start doing it.\nMore mundane the work, bigger the drive to fix it.\nAt the end you get a tool which helps you. Also which is created by you.\nOthers Can Benefit Too The problem which you are having there is a great chance others might be going through the same. If you manage to create that tool, open-souring it will help them too.\n",
      "date": "2022-03-07",
      "permalink": "https://iaziz786.com/blog/sustainable-person-project-approach/",
      "tags": ["open-source","projects","continuity"]
    }
    
    ,
    {
      "title": "How to Publish Your First Rust Crate?",
      "content": "You Need an Account Before you start publishing any crate to crates.io, you first have to create an account.\nGo to crates.io Login with GitHub Verify your Email Then Login Create a New Token form Account Settings in the API Access section Run the command you get to the login Get Your Project Ready Add the following fields in the Cargo.toml file license or license-file description documentation homepage or repository You need to commit your work before publishing Do a dry run by running cargo publish --dry-run Fix any errors or warnings after the dry run And Publish cargo publish Let the World Use Your Crate :) ",
      "date": "2021-11-17",
      "permalink": "https://iaziz786.com/blog/publish-first-rust-crate/",
      "tags": ["rust","crate","publish","crates.io"]
    }
    
    ,
    {
      "title": "How to Import Local Package in Golang?",
      "content": "Context While developing any go applications you might come into a situation where you need to use a module that is not yet ready to publish. The module might be living on your local machine and you wanted to get the taste of it using with other projects before shipping it. In this post, we will discuss what approach you can take to import a module that is still in development and before publishing it to the package registry.\nWe will write a simple project which takes a string and returns a boolean whether the string is valid IP address or not. The functionality is not that important but the important part is how we integrate it into another project while still making changes to the project.\nProjects Layout To keep things simple, I have created two projects which live side by side. The wip-module project is the unpublished one and the tester-module is the one in which will import the unpublished wip-module project. You can find the folder structure on Github.\nWIP Project The wip-module is a simple go module that holds the implementation of checking whether the IP is valid or not. Let\u0026rsquo;s look into the file:\nwip-module/ipchecker.go\npackage ipchecker import ( \u0026#34;net\u0026#34; ) func IsValidIP(host string) bool { if ip := net.ParseIP(host); ip != nil { return true } return false } This module does not have the main package which means it was intended to be used as a library in other projects.\nTester Project This is the project which will import the ipchecker package. Here is how it looks:\ntester-module/main.go\npackage main import ( \u0026#34;fmt\u0026#34; ipchecker \u0026#34;github.com/iAziz786/wipmodule\u0026#34; ) func main() { fmt.Println(\u0026#34;valid IP = \u0026#34;, ipchecker.IsValidIP(\u0026#34;127.0.0.1\u0026#34;)) fmt.Println(\u0026#34;valid IP = \u0026#34;, ipchecker.IsValidIP(\u0026#34;invalid-ip\u0026#34;)) } // Output: // valid IP = true // valid IP = false As you can see it\u0026rsquo;s using the ipchecker package from the github.com/iAziz786/wipmodule module. At this point, if you run the tester-module program you will see an error related to the package. Let\u0026rsquo;s glue them together!\nUsing Unpublished Modules Before we do anything let\u0026rsquo;s look at the go.mod file of the tester-module.\ntester-module/go.mod\nmodule github.com/iAziz786/testermodule go 1.16 require github.com/iAziz786/wipmodule v0.0.0-unpublished replace github.com/iAziz786/wipmodule v0.0.0-unpublished =\u0026gt; ../wip-module Since the module is not published we gave it a version (v0.0.0-unpublished) that does not exist yet but to make things work correctly.\nThe next step is to replace the import behaviour for the wipmodule. We can do this by telling the go compiler to replace the import for github.com/iAziz786/wipmodule with the local path of the module. Since they are siblings, I can use relative path dot (..) notation.\ngo mod edit -replace=github.com/iAziz786/wipmodule@v0.0.0-published=../wip-module go get -d github.com/iAziz786/wipmodule@v0.0.0-published This will add a replacement in the go.mod of the tester-module.\ntester-module/go.mod\nmodule github.com/iAziz786/testermodule go 1.16 require github.com/iAziz786/wipmodule v0.0.0-unpublished replace github.com/iAziz786/wipmodule v0.0.0-unpublished =\u0026gt; ../wip-module Can you notice a replace directive at the end of the file? It adds the logic to tell go get to use the implementation which is one level up in the wip-module.\nNow if you will run the program in the tester-module you will see this output:\n$ cd tester-module $ go run . # Output valid IP = true valid IP = false Note: Make sure to remove the replace directive from go.mod of the tester module before you commit your changes, otherwise go get will break in non-local environment.\nConclusion We have used the golang\u0026rsquo;s module replace directive to use the local go module which is not a published module to import it into the other projects.\nReference https://golang.org/doc/modules/managing-dependencies#unpublished\nhttps://golang.org/ref/mod#go-mod-file-replace\n",
      "date": "2021-05-10",
      "permalink": "https://iaziz786.com/blog/import-local-package-in-go/",
      "tags": ["golang","go","modules","unpublished","import-local-package","import","local","package","replace","go modules"]
    }
    
    ,
    {
      "title": "How to Work with Arbitrary JSON in Go?",
      "content": "Abstract Mostly, when you are working with data you know the schema in which you will receive that data, but there come times when you don\u0026rsquo;t know exactly what will be the structure you will end up receiving. We talk about how you can handle JSON data which are arbitrary in Go.\nJSON with a Fixed Structure When you receive JSON for which you already know the structure, it is pretty easy to work with. You create a struct and unmarshal the bytes to that struct and the JSON package will take care of the rest. Suppose you receive information about today\u0026rsquo;s dinner in JSON and everyday dinner has the following structure.\ntype Dinner struct { MainCourse string `json:\u0026#34;main_course\u0026#34;` Beverage string `json:\u0026#34;beverage\u0026#34;` HasDessert bool `json:\u0026#34;has_dessert\u0026#34;` } And you receive the following JSON value:\nfood := []byte(` { \u0026#34;main_course\u0026#34;: \u0026#34;Biryani\u0026#34;, \u0026#34;beverage\u0026#34;: \u0026#34;Coca Cola\u0026#34;, \u0026#34;has_dessert\u0026#34;: true } `) You just need to create a variable which can hold the value from JSON.\nvar dinner Dinner Eventually, decode the values to the dinner variable like this:\njson.Unmarshal(food, \u0026amp;dinner) Now, you can access those values through the fields on the struct. Lucky you, you have dessert for today 😋.\ndinner.MainCourse // Biryani dinner.HasDessert // true JSON That You Are Not Aware Let\u0026rsquo;s diverge our mind from food to shopping list :). Now assume every weekend you go to purchase some grocery and the items in the list keep changing each week. If you have to represent that into a struct, you got no luck!\nLike almost everything in Go where so much randomness is evolved, you have to use interfaces. More particularly an empty interface. You can represent your shopping list like this:\nvar shoppingList interface{} Because an empty interface can satisfy any type you can use that to do Unmarshaling.\nlistJSON := []byte(` { \u0026#34;food\u0026#34;: { \u0026#34;ketchup\u0026#34;: \u0026#34;1pc\u0026#34;, \u0026#34;noodles\u0026#34;: \u0026#34;1pc\u0026#34;, \u0026#34;rice\u0026#34;: \u0026#34;2Kg\u0026#34; }, \u0026#34;utensils\u0026#34;: { \u0026#34;knives\u0026#34;: 2, \u0026#34;forks\u0026#34;: 3 } } `) json.Unmarshal(listJSON, \u0026amp;shoppingList) At this point shoppingList looks like this:\nshoppingList = map[string]interface{ \u0026#34;food\u0026#34;: map[string]interface{ \u0026#34;ketchup\u0026#34;: \u0026#34;1pc\u0026#34;, \u0026#34;noodles\u0026#34;: \u0026#34;1pc\u0026#34;, \u0026#34;rice\u0026#34;: \u0026#34;2Kg\u0026#34; }, \u0026#34;utensils\u0026#34;: map[string]interface{ \u0026#34;knives\u0026#34;: 2, \u0026#34;forks\u0026#34;: 3 } } To access the data, you can make a type assertion to map[string]interface{}.\nlist := shoppingList.(map[string]interface{}) After that, you can access the values like a regular map. But for the values that are nested, you need to do a type assertion again.\nutensils := list[\u0026#34;utensils\u0026#34;].(map[string]interface{}) utensils[\u0026#34;forks\u0026#34;] // 3 Conclusion You can handle arbitrary JSON with the help of interfaces. You just need to pass an empty interface to the Unmarshal function and the JSON data. After a type assertion, you are good to use the arbitrary fields and their values.\n",
      "date": "2020-12-30",
      "permalink": "https://iaziz786.com/blog/golang-arbitrary-json/",
      "tags": ["golang","json","arbitrary","interface","map"]
    }
    
    ,
    {
      "title": "How to Use Embedding to Write Cleaner Code in Go?",
      "content": "Abstract Go is cleaner because it doesn\u0026rsquo;t support many of the features that tradition OO languages support. Less is more. Inheritance is one of those features but Go has a different style which can fulfil the necessity of inheritance. It\u0026rsquo;s called Embedding.\nWhat is embedding You can \u0026ldquo;borrow\u0026rdquo; the functionality of a struct or interface into another struct and interface respectively is called embedding. You can not embed an interface into a struct or vice versa.\nHow to create embedding To create an embedding you need to put a different struct or interface into a different one without naming the field.\ntype Morning struct { breakfast bool } type Routine struct { Morning // ⬅️ no field name makes it embedded } type Director interface { Direct() } type Producer interface { Produce() } type Creator interface { Director Producer } Embedding In Interface Interface when embedded is the union of all the methods present in all of the interfaces combined. If method Eat() is present on an interface and Sleep() on another then embedding them into an interface with Repeat() method will have all, Eat(), Sleep(), and Repeat() methods.\nEmbedding In Struct Embedding in a struct is where you can see the real power of Go. Not only the fields that defined type has but also the methods you can access them directly. How cool is that! Let\u0026rsquo;s continue with our Routine struct.\ntype Morning struct { breakfast bool } func (m Morning) hasBreakfast() bool { return m.breakfast } type Routine struct { Morning } r := Routine{} r.hasBreakfast() // false You also the embedded type will be a field name on the struct. For example, you can have:\ntype DailySports struct { Jog // field name Jog *Swim // field name Swim sports.Cycling // field name Cycling *sports.Tennis // field name Tennis } func (d DailySports) enrolledBySwimming() bool { return d.Swim.Speed } But you cannot have conflict while embedding. This makes sense otherwise you won\u0026rsquo;t know which one to pick.\nstruct { *Swim // ⛔ Now allowed *sports.Swim // ⛔ Not allowed } You can do all the things you can with the promoted fields but you can not use the field name present in the defined type while constructing the struct.\ntype Morning struct { breakfast bool } type Routine struct { Morning } r := Routine{breakfast: true} // ⛔ Not allowed Conclusion You can use embedding to use any defined type to used inside a struct and borrow all the functionality it has. You need to check that the names don\u0026rsquo;t clash otherwise you are good to go.\nReference https://golang.org/doc/effective_go.html#embedding https://golang.org/ref/spec#Struct_types ",
      "date": "2020-12-17",
      "permalink": "https://iaziz786.com/blog/clean-code-with-embedding-in-go/",
      "tags": ["golang","embedding","api","clean"]
    }
    
    ,
    {
      "title": "How to Handle Missing Fields From A Struct in Go?",
      "content": "Suppose you have a variable of type of the struct mentioned below which you wanted to Unmarshal.\ntype Building struct { WindowCount int `json:\u0026#34;window_count\u0026#34;` Doors int `json:\u0026#34;doors\u0026#34;` } In case the data is coming from an unreliable source, you can never be sure that the value you will receive will always have the correct format. You have to be cautious when working around data like this. If you are new in Go you might be wondering what will happen you Unmarshal and incorrect value?\nCompiler Loves Zero Values If you unmarshal the code into a variable you will get the zero value for the fields WindowCount, and Doors. Which in some case can lead to bug because you might have different logic for missing case.\nvar b Building json.Unmarshal([]byte(\u0026#34;\u0026#34;), \u0026amp;b) fmt.Printf(\u0026#34;%+v\\n\u0026#34;, b) // Output: // {WindowCount:0 Doors:0} Pointer To Rescue 🦸 If you have worked with pointers in languages like C, C++ you might have some opinion. You either like it or you hate it. Most people fall into the later group. Working with pointers in Golang is fun because things are declarative comparatively.\nIf you set field type to pointer of that type it will be nil in case the field is missing\ntype Building struct { WindowCount *int `json:\u0026#34;window_count\u0026#34;` Doors *int `json:\u0026#34;doors\u0026#34;` } Unmarshalling it has the following effect:\nvar b Building json.Unmarshal([]byte(`{\u0026#34;window_count\u0026#34;: 2}`), \u0026amp;b) fmt.Printf(\u0026#34;%+v\\n\u0026#34;, b) // Output: // {WindowCount:0xc000016170 Doors:\u0026lt;nil\u0026gt;} The WindowCount holds the pointer to integer which holds the value 2. Whereas since doors is missing from the JSON string it will set to nil thanks to the zero value of pointers. You can now write your logic in case of the absence of that value.\nConclusion Since the field of a struct is part of the contract of the struct it can\u0026rsquo;t go missing entirely instead you need to handle it little differently. Most preferable way is to convert the type to a pointer of the same type and when in some case the value is missing it will be set to the zero value, which is nil.\n",
      "date": "2020-12-09",
      "permalink": "https://iaziz786.com/blog/handle-missing-struct-fields/",
      "tags": ["golang","struct"]
    }
    
    ,
    {
      "title": "How to Auto Reload Golang Applications?",
      "content": "You wanted to develop quick, you wanted to develop fast and there is nothing more tedious for a developer than doing the same thing again and again.\nI really HATE doing repetitive work. Probably that\u0026rsquo;s why I become a programmer to automate the boring stuff.\nFoundation (a server) I have been exploring Go, you might be aware since my previous post was written for itself. You can spin up a simple Go server with the following code.\npackage main import \u0026#34;net/http\u0026#34; func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, \u0026#34;hello\u0026#34;) } func main() { http.HandleFunc(\u0026#34;/echo\u0026#34;, handler) http.ListenAndServe(\u0026#34;:3000\u0026#34;, nil) } The above code creates a simple server that listens on port 3000 and if you hit http://localhost:3000/echo you will receive \u0026ldquo;hello\u0026rdquo; as a message.\nTo run the go server we should run the command below\ngo run . I call this the \u0026ldquo;tedious code\u0026rdquo;. I don\u0026rsquo;t care about it but I care what it does for me, it runs my application.\nI want changes, right now! Now, if you do any changes to the code you have run the \u0026ldquo;tedious code\u0026rdquo; again, and again, and again\u0026hellip;\nYou get it 🙄\nIf you are a lazy developer you must be thinking about what is the the better way to do it?\nYour computer can help you will that for sure.\nConventional way One of the most popular ways to auto-reload your application on any kind of change is by using air.\nIt is written in, no surprise, Go.\nTo install head over to their installation section. Do it, so that you can follow along. If you are feeling lazy then last time when I check their docs this was the command to do it.\ncurl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin Is it done? Good.\nThis command has two parts. First, to download the binary and second, to move the binary to Go\u0026rsquo;s binary path. The binary path is at $(go env GOPATH)/bin.\nWith all the things in place, you might be ready to start using the air command. But let\u0026rsquo;s verify it first. Does the below command works?\nair -v If it is, great! If not and you might be getting a command not found error. Most probably the Go binary is not set to your shell\u0026rsquo;s path. Usually, it\u0026rsquo;s fixed by adding the below command to your shell\u0026rsquo;s resource file (e.g. .zshrc, .bashrc):\nexport PATH=$PATH:$(go env GOPATH)/bin Open a new shell after adding the above line so new changes are reflected. Now the previous command should be working.\nThe next step, run the application! Move to the application which you want to run with the auto-reload feature and just start it with the command mentioned:\nair This will start your application and when you make any changes it will listen to those and reload it automatically.\nUnconventional way If you are/were a JavaScript developer you might be familiar with the steps mentioned onwards.\nFirstly, you need to install Node.js.\nI know, you must be thinking about how Node.js can help you to reload your Go code? Just bear with me and you will know how.\nOnce Node.js is installed on your system you will be able to run the command below.\nnpm install -g nodemon It will install a package called nodemon in your system and you will be able to run it from the command line.\nCommand to Auto Reload Now you can start you Go application with the command mentioned below.\nnodemon --exec go run . --ext go Let\u0026rsquo;s break it down.\nIt will watch for any files with .go extension in the current directory and if any change in the go files will execute the go run . command again.\nSummary You can reload your server apps or any other app which needs a constant restart to reflect the changes by using tools like air and nodemon. Although both methods get your job done I personally use the air cli to reload my app because I find it fast and easier to use.\n",
      "date": "2020-11-30",
      "permalink": "https://iaziz786.com/blog/golang-auto-reload-apps/",
      "tags": ["golang","reload","auto-reload","application","server"]
    }
    
    ,
    {
      "title": "Merge Sort In Go",
      "content": "What is sorting? Sorting is a way to organize data in certain order.\nWhat are these orders?\nIt depends on the task and also on the type of data we are working with. For example, for number you can sort them in ascending or descending order of their values. And for text you can do the same based on the occurrence their character.\nWhat\u0026rsquo;s a \u0026ldquo;merge\u0026rdquo; sort? It is a way to sort any data in which we divide the given task in subtasks (in half) and ultimately merging those subtasks into one which gives us the sorted list of the data which we want.\nHere is a nice gif from WikiPedia for more graphical explanation.\nIt follows the divide and conquer design paradigm.\n👨‍💻 Let\u0026rsquo;s write code Suppose we have a list of array which holds integers. We will now write some Go code which will sort the integers using merge sort.\nSince merge sort uses divide and conquer technique, it recursively do a function call to itself with the subtask and eventually merge the subtask into a single value of the sorted data.\nThis is how the merge step looks like.\n🧪 Writing the test case first package merge_sort import ( \u0026#34;reflect\u0026#34; \u0026#34;testing\u0026#34; ) func TestMergeSort(t *testing.T) { var tests = []struct { message string in []int out []int }{ { \u0026#34;should return single value when input is single\u0026#34;, []int{3}, []int{3}, }, { \u0026#34;should sort values in random order\u0026#34;, []int{3, 1}, []int{1, 3}, }, { \u0026#34;should return empty array if the input is also empty\u0026#34;, []int{}, []int{}, }, { \u0026#34;should sort values with duplication\u0026#34;, []int{3, 2, 3}, []int{2, 3, 3}, }, { \u0026#34;should sort values with negative cases\u0026#34;, []int{-9, 2, 3, -3}, []int{-9, -3, 2, 3}, }, } for _, tt := range tests { t.Run(tt.message, func(t *testing.T) { MergeSort(tt.in, 0, len(tt.in) - 1) if reflect.DeepEqual(tt.in, tt.out) != true { t.Errorf(\u0026#34;got %q, want %q\u0026#34;, tt.in, tt.out) } }) } } Merge Step // Merge left and right arrays // start - start index of the array // middle - middle index of the array // end - end index of the array func Merge(input []int, start, middle, end int) { itemsAtLeftSide := middle - start + 1 itemsAtRightSide := end - middle // creating arrays which holds one extra element then the // currently needed because of the sentinel assignment left := make([]int, itemsAtLeftSide + 1) right := make([]int, itemsAtRightSide + 1) // allocate elements in the left side of the array for i := 0; i \u0026lt; itemsAtLeftSide; i++ { left[i] = input[start + i] } // allocate elements in the right side of the array for j := 0; j \u0026lt; itemsAtRightSide; j++ { // adding one because because j index is staring from zero // which in most of the cases conflict with the value in // the left array, adding one removes the conflict element right[j] = input[middle + j + 1] } // sentinel assignments left[itemsAtLeftSide] = math.MaxInt64 right[itemsAtRightSide] = math.MaxInt64 for i, j, k := 0, 0, start; k \u0026lt;= end; k++ { if left[i] \u0026lt;= right[j] { // assign what is at the top of the left array input[k] = left[i] i++ } else { // assign what is at the top of the right array input[k] = right[j] j++ } } } The Sorting Code In merge sort the main part where we divide the task in half is simple. The real meat is the merging step which we have mentioned above.\nfunc MergeSort(input []int, start, end int) { if start \u0026lt; end { // getting the middle value middle := (start + end) / 2 // sort whatever in the left of the array MergeSort(input, start, middle) // sort whatever in the right of the array MergeSort(input, middle + 1, end) // merge left and right sorted values Merge(input, start, middle, end) } } Playground Code 🏌️‍♂️ You can reach at the playground by following the link.\n",
      "date": "2020-08-16",
      "permalink": "https://iaziz786.com/blog/merge-sort-in-go/",
      "tags": ["sorting","merge-sort","go","divide-and-conquer"]
    }
    
    ,
    {
      "title": "Hello Internet",
      "content": "Hello World! Welcome to my space on the Internet. My name is Mohammad Aziz I\u0026rsquo;m a software developer at Zoop.one. My role is as Full-Stack Developer. That means, I wear many of hats 🎩.\nNowadays, I\u0026rsquo;m reading a book by Shaw Wang on coding career and inspired by the book I decided to do what I wanted to do since about a year. I purchased https://iAziz786.com and started my journey today.\nI will start writing about the things I learn each day at work. Maybe I won\u0026rsquo;t be writing about them each day but after a couple of days, combining my findings and write about. I hope you find this a interesting place to be at and I\u0026rsquo;ll try to provide as valuable information possible.\nI\u0026rsquo;m keeping this blog short for now because I\u0026rsquo;m very tired today and also because I need to push these codes just now.\nTo wrap up, this is the context about the platform. I\u0026rsquo;m a JavaScript developer that means you can expect posts about TypeScript, Node.js, React.js and may more things. I\u0026rsquo;m also interested in Go but don\u0026rsquo;t use it more frequently at work so my experience with Go is not as good as JavaScript but it\u0026rsquo;s improving.\n",
      "date": "2020-08-01",
      "permalink": "https://iaziz786.com/blog/hello-internet/",
      "tags": ["introduction","first-blog"]
    }
    
    ,
    {
      "title": "",
      "content": "Grew up in Midnapore, West Bengal, India. Small town which is growing fast.\nI am curious to learn how the world works. Each day I\u0026rsquo;m discovering something new. The same curiosity brought me closer to computers. I find them fascinating and no less than magic.\nDo not aim for being right, aim for being less wrong.\nRunning selfhost.dev with my co-founders. We help people host their own stuff without losing their minds.\n",
      "date": "0001-01-01",
      "permalink": "https://iaziz786.com/about/",
      "tags": []
    }
    
    ,
    {
      "title": "",
      "content": "",
      "date": "0001-01-01",
      "permalink": "https://iaziz786.com/projects/",
      "tags": []
    }
    
    ,
    {
      "title": "Search",
      "content": "",
      "date": "0001-01-01",
      "permalink": "https://iaziz786.com/search/",
      "tags": []
    }
    
  ]
}