<?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"><channel><title><![CDATA[Neel Vikmani]]></title><description><![CDATA[Neel Vikmani]]></description><link>https://neelvikmani.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 04 Sep 2026 12:12:41 GMT</lastBuildDate><atom:link href="https://neelvikmani.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to create effective tech documentations]]></title><description><![CDATA[In this article, I will be sharing how you can create and manage tech documentation more effectively. This will be helpful not only for someone who is starting a new team or a new project but also for a person who is working on an existing product wh...]]></description><link>https://neelvikmani.hashnode.dev/how-to-create-effective-tech-documentations</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/how-to-create-effective-tech-documentations</guid><category><![CDATA[Software Engineering]]></category><category><![CDATA[Technical writing ]]></category><category><![CDATA[software development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[GitHub]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Thu, 25 May 2023 11:44:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1684697098091/bcadf9a6-0aec-41fd-95ae-dd89e1205e30.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will be sharing how you can create and manage tech documentation more effectively. This will be helpful not only for someone who is starting a new team or a new project but also for a person who is working on an existing product which does not have proper tech/team documentation yet.</p>
<p><strong>Ideally, technical documentation</strong> should explain everything about your software product, ranging from internal documentation for the team to external documentation for end-users or other teams. It should contain all the details relating to software products like product designs and requirements, engineering designs, decision records, API contracts, etc.</p>
<h3 id="heading-why-create-and-manage-tech-docs">WHY create and manage tech docs 💡</h3>
<p><strong>More effective team collaboration 👏</strong></p>
<p>The team can collaborate better if there is a written note of everything that is currently being worked on. It could even be something that is not yet picked up for work but is finalized for development, like API Contracts, multiple feature tasks, etc. This becomes much more important in a remote job setup.</p>
<p><strong>Improves tech on-call support effectiveness</strong></p>
<p>Tech documentation including the playbooks for commonly faced production issues and support can improve the on-call support effectiveness. This ensures that the team knows and follows the documented SOPs for a certain set of production use cases.</p>
<p><strong>Future references and decision making 👀 🧠</strong></p>
<p>Consider you are working on a service, where you are expected to design and develop the service completely from scratch. There are a lot of important decisions you need to take at this point, like language choice, system architecture, end-to-end user flow, database, cache, messaging queues choices, schema design, etc.</p>
<p>You might have explored a lot of choices before finalizing each of these. It becomes extremely important to document these <strong>decision records</strong> with all the minute details so that they can be referred to in future if there are similar use cases. This could also be useful for any <strong>new joiner</strong> who wants to understand the system better and know <strong>why</strong> we built the system the way we built it.</p>
<p>This also holds true for any modifications in the existing service as well, so that the new devs can understand the trailing changes and the evolution of the service since inception instead of going through the git history, chats and emails.</p>
<h2 id="heading-how-to-create-a-tech-doc">How to create a tech doc 📑</h2>
<p>To start with a team / tech documentation, you can use any preferred choice of documentation platform. I personally like using Confluence docs, but you can choose any other platform as well like git books, or even Google Docs.</p>
<p>You can follow the below template. Note that each point in itself is a separate doc. and the main root doc <em><mark>&lt;Team Name&gt;</mark></em> can have links for each of the child docs</p>
<hr />
<h3 id="heading-ltteam-namegt"><strong><em><mark>&lt;Team Name&gt;</mark></em></strong></h3>
<ul>
<li><p><strong>Members</strong></p>
<p>  <em>This doc should contain information on each team member, like name, email, designation, etc.</em></p>
</li>
<li><p><strong>Onboarding Steps</strong></p>
<p>  <em>This doc should highlight all the things that are required for onboarding a new member to the team. This could include listing all the tools, and software needed to set up the codebase locally and also include</em> <strong><em>access</em></strong>-related queries. This doc should also mention in short what the team does and what services (which will be listed below) it handles.</p>
</li>
<li><p><strong>Product Plans and Logs</strong></p>
<p>  <em>This doc should have links to all the PRDs created and shared by the Product from time to time.</em></p>
</li>
<li><p><strong>Service#1: <em><mark>&lt;Service Name&gt;</mark></em></strong></p>
<ul>
<li><p><strong>Developer Docs</strong></p>
<ul>
<li><p><strong>Architecture and components</strong></p>
<p>  <em>This doc should include the HLD(high-level architecture diagrams) of the service and also list all the components used by this service, along with a short explanation, like it's DB, messaging queues, external services, etc.</em></p>
</li>
<li><p><strong>API docs</strong></p>
<p>  <em>This doc should contain the link to Swagger/API documentation created by the developers of this service.</em></p>
</li>
<li><p><strong>Integration</strong></p>
<p>  <em>This doc should mention all the steps that need to be followed to integrate the service into any environment. This could even include steps to request credentials like client-id/secret, etc. to get access to APIs or include additional information on the best practices to follow while integration.</em></p>
</li>
</ul>
</li>
<li><p><strong>Operational Docs</strong></p>
<ul>
<li><p><strong>Deployment steps and details</strong></p>
<p>  <em>This doc should include detailed steps on how features should be deployed into production and also include pre-deployment(like re-running the previous package build to make sure we have the previous revert version) as well post-deployment steps(like monitoring and revert strategies in case of any incident).</em></p>
</li>
<li><p><strong>Production support playbook</strong></p>
<p>  <em>This doc should mention all the steps and answers to common queries which arise on production support. This could range from customer complaints related to data sync issues or include strategies for resolving system-related issues like the most commonly occurring burst throughput latency spikes, etc.</em></p>
</li>
</ul>
</li>
<li><p><strong>Architecture Decision Records(ADRs)</strong></p>
<p>  <em>This should include links to all the ADRs documented till now. Each file inside this section should be an individual ADR in the below format.</em></p>
<ul>
<li><p><strong>ADR0001 - &lt;ADR Title&gt;</strong></p>
</li>
<li><p><strong>ADR0002 - &lt;ADR Title&gt;</strong></p>
</li>
</ul>
</li>
<li><p><strong>RFCs</strong></p>
<p>  <em>This should include links to all the RFCs documented till now. Each file inside this section should be an individual RFC in the below format.</em></p>
<ul>
<li><p><strong>RFC0001 - &lt;RFC Title&gt;</strong></p>
</li>
<li><p><strong>RFC0002 - &lt;RFC Title&gt;</strong></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>    <em>(Ideally, each individual ADRs / RFCs should also follow a predefined format which can be decided by your team. The idea behind this is to make the docs informative, crisp, consistent so that it is easier to review and maintain.)</em></p>
<hr />
<p>Apart from the documents and sections mentioned above, you may add any other section as well based on your use case. For example: if you want to have a log of your previous tasks and the estimations, or even Action items you can add a section like <strong>Internal docs</strong> within which you can mention the details as per your requirement.</p>
<p>Once you create such tech documentation, it is extremely important to keep it updated as and when any change occur. If not daily, then atleast this should be updated once a week whenever change is required so that the documentation is fresh and always updated.</p>
<hr />
<p>I hope you find this article helpful. If so, please like, comment and share this article 😃.</p>
<p>Let's connect 💫</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>You can also subscribe to my newsletter below to get an email notification on my latest posts. 💻</p>
]]></content:encoded></item><item><title><![CDATA[My journey as a Software Engineer at a fast growing startup]]></title><description><![CDATA[In this article, I will share what is it like to work as a Software Engineer at a fast-growing startup. I will share my journey and experiences working as a Software Engineer in the past few years. In the end, I will also share some learnings that yo...]]></description><link>https://neelvikmani.hashnode.dev/my-journey-as-a-software-engineer-at-a-fast-growing-startup</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/my-journey-as-a-software-engineer-at-a-fast-growing-startup</guid><category><![CDATA[software development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[Startups]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Sun, 19 Feb 2023 11:10:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/607b3f66f001369e70e861117bb824c0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will share what is it like to work as a Software Engineer at a fast-growing startup. I will share my journey and experiences working as a Software Engineer in the past few years. In the end, I will also share some learnings that you can take note of if you are also someone who is going to start or just started working as a Software Engineer.</p>
<h2 id="heading-a-little-background-about-myself"><strong>A little background about myself</strong>  🙋‍♂️</h2>
<p>After graduating a couple of years back, I started working as a Software Engineer at a leading healthcare startup in India. Being passionate about startups, I always wanted to work at one of those, as I had heard many great things about work culture and the quality of work exposure that people get.</p>
<p>In my college days, I was mostly involved in full-stack web development and had mostly worked on PHP and MEAN(MongoDB, ExpressJs, Angular and NodeJs) stack.</p>
<h2 id="heading-the-startup-journey"><strong>The startup journey</strong> 🌟</h2>
<p>I started my full-time job as a Software Engineer. I was working as a backend engineer in one of the most critical and core teams of the startup which dealt with the catalogue of products and their various properties.</p>
<h2 id="heading-the-project-that-i-was-part-of"><strong>The project that I was part of</strong> 💻</h2>
<p>My team was responsible for all things about the product not only the static information that gets shown on the website but also its dynamic properties like its stock availability, price, discounts, etc which are calculated at each city level throughout India <strong>in real-time</strong>.</p>
<p>Apart from this, our project also had various algorithms and logic which dealt with showing substitutes / similar products in case the requested product was not available in a particular city in real-time.</p>
<p>It was a monolith project back then and was developed using <strong>Ruby on Rails</strong>, <strong>Redis</strong> and <strong>MySQL</strong>.</p>
<p>The first couple of months were pretty intense for me with lots of learning and understanding of the product, system and this new tech stack.</p>
<p>After the first six months, I was pretty comfortable working on medium-sized features and a few large-sized features with some guidance from my team members.</p>
<h2 id="heading-coping-up-with-the-scale">Coping up with the scale 🏹</h2>
<p>Then COVID hit India by late 2019. During this time, our startup being in the healthcare e-commerce domain got unimaginable 3x boosts in growth. With this, even the product, audiences and features grew in numbers and size and existing systems started becoming overhead in terms of maintenance and scale.</p>
<p>We started doing optimisations in the existing code and infrastructure, like <strong>upscaling the application and database servers</strong>, optimising the code, <strong>optimising database</strong> and <strong>cache queries</strong>, etc. All these helped us to a certain extent but were still not much performant. At the same time, we also saw a few changes in the business models which could mean major changes in our services. So we had to think of a long-term solution to cope with this scale and extensibility, keeping in mind that the tech for these new business changes should be scalable and maintainable.</p>
<p>So we decided to <strong>split this single monolith into multiple small independent services</strong> so that they can be scaled and maintained independently. The new tech stack chosen was Java(Springboot Webflux), Redis, Kafka and MongoDB to keep in line with the newer requirements and the increasing scale.</p>
<h2 id="heading-the-journey-from-here"><strong>The journey from here</strong> 💫</h2>
<p>Being in the core and critical team of the company, I got a chance to directly work towards these things. The next six months were crazy in terms of learnings in the new tech stack again, managing multiple services and trying to cope with the rapid growth. But as difficult as it seems, it was immensely wonderful in knowing and being part of this journey.</p>
<p>It was during this period that I got a whole new set of experiences which I could have never got otherwise, to work from scratch on building the micro-services end to end and migrate the live traffic from monolith service to these micro-services without any business interruption.</p>
<p>At this point, I not only learned about product development but also about how the systems are built at <strong>scale</strong> and what it means to build a <strong>distributed system</strong>. Our team as well grew in size and I was also mentoring new joiners. I also started making proper documentation so that it's easier for the new joiners to refer to it. All this happened in a matter of just <strong>1</strong> year!</p>
<p>So by the end of 2 years into this startup where I joined as a fresher, I had worked on a monolith system, later transformed the system into microservices, migrated the live traffic to these new services, guided new joiners and also made significant tech documentation for our team.</p>
<h2 id="heading-my-observations"><strong>My observations</strong> 🕵🏻‍♂️</h2>
<p>There were a couple of things that I loved about this experience.</p>
<p>There was a lot of flexibility for trying out things. It does not matter if you are a fresher or a senior; if you prove that you are capable of doing what is required, then you can get great opportunities and chances to work on some amazing projects with some amazing teams.</p>
<p>In startups, there are fewer processes in place which enable teams to work more on the features that matter the most and deliver them in less time, which might not be possible in some big tech companies.</p>
<p>People are also extremely friendly and transparent in most startups, be it a fresher or most senior technical architect/lead, the people are almost always willing to help.</p>
<p>The pace of a startup is much faster compared to a bigger organisation. This also means you get to contribute a lot to the startup growth journey. So just after a year or two, if you had built great products, or worked with an amazing team on good projects, the work experience and work ethic you gain and exhibit helps you become a great software engineer ahead.</p>
<h2 id="heading-my-learnings"><strong>My learnings</strong> 💡</h2>
<p>Apart from the experiences that I have shared above, I am also sharing a few learnings below that I got while working, which helped me grow personally and professionally.</p>
<ul>
<li><p>Initially, after spending some time on the tech stack, you get used to it and coding in itself becomes easy. As a next step, try to understand the complete product/project you are working on.</p>
<ul>
<li><p>Try to get overall high-level knowledge of your system. Read through the Architecture docs, RFCs, and decision records designed for your system.</p>
</li>
<li><p>Read the product documents(PRDs, research docs, etc) to know the historical metrics of previous versions of your product and how it has evolved.</p>
</li>
<li><p>Be proactive in resolving queries raised by customers/other teams. This will help you to know your system better</p>
</li>
<li><p>Spend time understanding your service metrics, like the API latencies, throughput patterns, database latency, time-consuming database queries, etc. For this, you can start being actively involved in the service deployments/release, as the team would usually be monitoring all these metrics after any deployment.</p>
</li>
<li><p>Always think about optimising the system as much as you can.</p>
</li>
</ul>
</li>
<li><p>Always speak up, no one else might speak for you. Whatever you do, make sure you keep your team well-informed to avoid any confusion.</p>
</li>
<li><p>If the potential release feature affects the team or other stakeholders, call out early to the team and the stakeholders. Never hesitate to come up with any new idea or findings, be it extremely silly or serious, it can have a huge impact sometimes. Don't wait for other folks in the team to figure it out later. <strong>Be proactive</strong>.</p>
</li>
<li><p>There are instances where changes at one level might affect other areas too in your service, that's why unit, regression, and sanity tests are most important to do even if you are a developer. Always think about the modularization of the project/feature that you are developing. Avoid code smells! Do a thorough dev testing of your changes before raising a merge request with the team.</p>
</li>
<li><p>If other teams are integrated with your service or actively using your services, then it is <strong>your responsibility</strong> to support and help them regarding any of the queries or problems they are facing while using your service APIs, events, etc.</p>
</li>
<li><p>Always try to be present and actively support your team. This also helps to build credibility and trust in your team.</p>
</li>
<li><p>Show <strong>extreme ownership</strong> in the features you are working on. Be proactive in understanding the feature, asking doubts, reaching out to stakeholders for the changes, etc. This will help you grow further as a Software Engineer and also build trust within the team.</p>
</li>
<li><p><strong>Take breaks!</strong> Only working all day and doing nothing else will eventually lead to burnout after some time. Make sure you take breaks in between. Play sports, go travel, trek or do something different that you like apart from work. This will help you in being more productive at work as well and also maintains your mental and physical health.</p>
</li>
</ul>
<hr />
<p>That's it from my end. Please like or comment below if you like this or if you want to share your startup experiences as well. 😃</p>
<p>Let's connect 💫</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>I am planning to write frequently on various Software Engineering topics, you can subscribe to my newsletter below so that you get an email notification on my latest post. 💻</p>
]]></content:encoded></item><item><title><![CDATA[Transactions in Redis]]></title><description><![CDATA[In this article, we will be seeing how Redis supports transactions and locks.
Similar to other databases, Redis also supports transactions via which we can run multiple Redis operations in a single atomic step. By ensuring atomicity and isolation, Re...]]></description><link>https://neelvikmani.hashnode.dev/transactions-in-redis</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/transactions-in-redis</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Redis]]></category><category><![CDATA[software development]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Fri, 10 Feb 2023 17:05:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676047598519/9e5c91fe-8e9c-4b8a-9f85-ad5512063b86.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will be seeing how Redis supports transactions and locks.</p>
<p>Similar to other databases, Redis also supports transactions via which we can run multiple Redis operations in a single atomic step. By ensuring atomicity and isolation, Redis ensures that the request sent by another client will never be served in the middle of the execution of a Redis transaction.</p>
<p>Redis also supports <strong>an Optimistic locking</strong> mechanism via which we can guarantee that the variables used inside the transactions are not updated by any other thread or another execution context.</p>
<p>Redis supports these capabilities using the <code>MULTI</code>, <code>EXEC</code> , <code>DISCARD</code> and <code>WATCH</code> commands.</p>
<p>In the below section, we will use these commands and operate them over a few Redis key string data.</p>
<blockquote>
<p>By the way, if you don't know much about Redis data structures and how we set/get the values from Redis, I would recommend checking out <a target="_blank" href="https://blog.neelvikmani.com/redis-data-structures"><em>this article</em></a> before proceeding.</p>
</blockquote>
<h2 id="heading-transactions">Transactions</h2>
<p>Let's consider the below example where we set two Redis keys <code>foo</code> and <code>bar</code> with values 1 and 2 respectively via our local redis-cli.</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; SET foo 1
OK
127.0.0.1:6379&gt; SET bar 2
OK
</code></pre>
<p>Now let's increment the values of both these variables by 1, but instead of executing in 2 steps, do it as a single atomic transaction.</p>
<p>To start a transaction, we use <code>MULTI</code> following the set of commands we want to run, and then finally we use <code>EXEC</code> if we want to execute the transaction.</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; MULTI
OK
127.0.0.1:6379(TX)&gt; INCR foo
QUEUED
127.0.0.1:6379(TX)&gt; INCR bar
QUEUED
127.0.0.1:6379(TX)&gt; EXEC
1) (<span class="hljs-built_in">integer</span>) 2
2) (<span class="hljs-built_in">integer</span>) 3
127.0.0.1:6379&gt; MGET foo bar
1) <span class="hljs-string">"2"</span>
2) <span class="hljs-string">"3"</span>
</code></pre>
<p>As you might have noticed, once we run any operations inside the <code>MULTI</code> <code>EXEC</code> block, the output is stated as <code>QUEUED</code>. This means that the operation is not executed but is enqueued to be executed once we run <code>EXEC</code>.</p>
<p>As we run <code>EXEC</code> command, the operations are executed first-in-first-out (being a queue) and the results are returned in the same order.</p>
<p>Similarly, instead of <code>EXEC</code> command to execute transactions, we can use the <code>DISCARD</code> command to discard the operations mentioned inside the transaction block.</p>
<h2 id="heading-errors-in-transaction">Errors in transaction</h2>
<p>There could be 2 types of errors in Redis transactions</p>
<ol>
<li><p>Errors happening before the <code>EXEC</code> command</p>
<ul>
<li>This could occur due to a syntax error for running the command, like a wrong command name or wrong number of arguments.</li>
</ul>
</li>
<li><p>Errors happening after the <code>EXEC</code> command</p>
<ul>
<li>This could happen in cases where we operate against a key with the wrong value(for example: calling <code>INCR</code> against a key which holds a string value).</li>
</ul>
</li>
</ol>
<p>For errors happening after the <code>EXEC</code> command, Redis <strong>does not</strong> support the rollback of operations in case one of them fails. Even if one of the executions of the operation fails, all the other commands in the queue are still processed and are not rolled back.</p>
<h2 id="heading-optimistic-locking-on-transaction-attributes">Optimistic Locking on transaction attributes</h2>
<p>Let's consider a scenario where there are 2 redis clients which are trying to increment the value <code>foo</code> at the same time. We can simulate this on the local system by running the <code>redis-cli</code> on 2 CLIs / terminal tabs.</p>
<p>Currently, we have the value of <code>foo</code> as <code>"2"</code> based on the commands executed in the previous sections.</p>
<p>In the <strong>first cli tab</strong>, run the below command</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; MULTI
OK
127.0.0.1:6379(TX)&gt; INCR foo
QUEUED
</code></pre>
<p>Now in the <strong>second cli tab</strong>, simply increment the foo value without any transaction like below</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; INCR foo
(<span class="hljs-built_in">integer</span>) 3
</code></pre>
<p>Now, if we run <code>EXEC</code> command on the <strong>first cli tab</strong>, it will increment the value of <code>foo</code> again.</p>
<pre><code class="lang-bash">127.0.0.1:6379(TX)&gt; EXEC
1) (<span class="hljs-built_in">integer</span>) 4
127.0.0.1:6379&gt; GET foo
<span class="hljs-string">"4"</span>
</code></pre>
<p>As you can see, it updates the value to <strong>4</strong>, since the second tab already incremented it once from <strong>2</strong> to <strong>3</strong>. This is known as a race condition, where multiple clients can race to update the value of the same attribute.</p>
<p><strong>Redis supports optimistic locking via</strong> <code>WATCH</code> <strong>command. Using this command, we can ensure that the transaction is not executed if the attributes inside it have been updated by some other client.</strong></p>
<p>Run the below commands in the <strong>first tab</strong></p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; WATCH foo
OK
127.0.0.1:6379&gt; MULTI 
OK
127.0.0.1:6379(TX)&gt; INCR foo
QUEUED
127.0.0.1:6379(TX)&gt; INCR bar
QUEUED
</code></pre>
<p>Now, again increment the value of foo from the second tab</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; INCR foo
(<span class="hljs-built_in">integer</span>) 5
</code></pre>
<p>Now, back from the first tab, try to run <code>EXEC</code> command. It will return the value as (nil)</p>
<pre><code class="lang-bash">127.0.0.1:6379(TX)&gt; EXEC
(nil)
</code></pre>
<p>This means that none of the operations inside the transaction was executed(or we can say that the transaction was aborted) because the value of foo(which was being "<strong>watched</strong>" by the transaction) was updated by some other client.</p>
<p>This <code>WATCH</code> command can be called multiple times. Also, we can pass multiple keys to <code>WATCH</code> in a single command, like <code>WATCH foo bar</code>. All the keys mentioned in <code>WATCH</code> command are watched for modifications up to the moment <code>EXEC</code> is called.</p>
<p>Once <code>EXEC</code> is called, all keys are <code>UNWATCH</code>ed, regardless of whether the transaction was aborted or not. Similarly, when a client connection is closed, everything gets <code>UNWATCH</code>ed.</p>
<blockquote>
<p>Since this is an Optimistic locking mechanism, the client has to retry the transactions if it fails, until there is no race condition with other clients.</p>
</blockquote>
<hr />
<p>I hope you find this article helpful. If so, please like, comment and share this article 😃.</p>
<p>Let's connect 💫</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>You can also subscribe to my newsletter below to get an email notification on my latest posts. 💻</p>
]]></content:encoded></item><item><title><![CDATA[Basics of Terraform: Why, What and How]]></title><description><![CDATA[Before jumping directly into what is terraform, let's build an understanding of the basics, like what is IaC, what problems it solves and what is terraform.
Then we will see how to use terraform to create and manage the resources by taking an example...]]></description><link>https://neelvikmani.hashnode.dev/basics-of-terraform-why-what-and-how</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/basics-of-terraform-why-what-and-how</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Devops]]></category><category><![CDATA[software development]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Sun, 05 Feb 2023 04:42:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1675515620081/1a7cc864-4b61-48ad-8fcc-e53f10eb5148.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before jumping directly into what is terraform, let's build an understanding of the basics, like what is IaC, what problems it solves and what is terraform.</p>
<p>Then we will see how to use terraform to create and manage the resources by taking an example of a basic local file resource.</p>
<h2 id="heading-problem">Problem</h2>
<p>Long back in the pre-cloud era, the total turnaround time of provisioning the infrastructure resources would range from a few days to months. Scaling the infrastructure on demand was also not quick. The things were not automated which would also lead to human errors as well.</p>
<p>With the advent of cloud platforms, the time to spin up infra and time to market applications significantly reduced, making it much more efficient than the traditional IT processes.</p>
<p>With cloud platforms, we do not have to manage actual hardware assets like the traditional IT model. The data centre and hardware assets are managed by cloud providers. These cloud providers have a <em>management console</em> - a nice UI via which you can provision resources. <strong>But still, there were a few problems here.</strong></p>
<p>Once provisioned, systems still go through different teams and a lot of process overhead, which could again take time and also lead to human error, hence again this approach was not feasible in large organizations.</p>
<h2 id="heading-solution">Solution 💡</h2>
<p>The cloud providers also exposed a set of APIs via which we could automate infrastructure provisioning. This opened up a whole new world of automation.</p>
<p>Initially, every company was solving the same problem of writing some scripts trying to automate infra provisioning, installing required software on infra, configuration, and deploying faster and consistently by leveraging the APIs of these cloud providers. These tools eventually paved the way for <strong>IAC(Infrastructure as Code)</strong>. Several IAC tools were developed later which solved the problems that everyone was facing.</p>
<p>Infrastructure as Code, as the name implies means writing and executing code to create, update or destroy infrastructure components. With IACs, we can manage any infrastructure components like compute instances, databases, network components, etc. by writing it in a simple human-readable <strong>high-level</strong> language.</p>
<p>There are various types of IACs currently present like Terraform, Ansible, AWS Cloudformation, etc.</p>
<h3 id="heading-types-of-iac-tools"><strong>Types of IAC tools: 🛠</strong></h3>
<p><strong>Configuration management tools</strong> - These tools are commonly used to install and manage software on <strong>existing infrastructure</strong> like servers, networking devices, etc. The most commonly used tools in this category are Ansible, Chef, puppet, etc.</p>
<p><strong>Sever templating tools -</strong> These tools are used to create a custom image of a VM or a container. These images already contain all the required software and dependencies on them, hence eliminating the need to install software or additional dependencies once they are deployed, hence making them immutable. This includes tools like <a target="_blank" href="https://blog.neelvikmani.com/basics-of-docker-why-what-and-how">Docker</a>, Packer or Vagrant.</p>
<p><strong>Provisioning tools -</strong> These tools allow the provisioning of infrastructure components ranging from compute resources, VMs, VPC, or even database and network components. <strong>Terraform</strong> is the most common and widely used IaC tool in this category.</p>
<h2 id="heading-terraform"><strong>Terraform 🏗</strong></h2>
<p>Terraform is an IAC tool which allows us to manage and destroy infrastructure.</p>
<p>There are other resource provisioning IAC tools like AWS Cloudformation but they allow creating resources only on AWS.</p>
<p>One of the best parts about terraform is that it is <strong>vendor-agnostic</strong>. We can use Terraform to provision and manage infrastructure on any major cloud provider. Terraform has provider plugins which we can use for all major cloud providers.</p>
<p>Another best thing about terraform is its ability to deploy infrastructure across multiple platforms including private or public cloud, on-premises or various cloud providers.</p>
<p><strong>How does terraform manage infrastructure on so many different platforms?</strong></p>
<p>It is achieved through the <strong>Provider!</strong></p>
<p>Providers are a logical abstraction of an upstream platform API. These providers enable terraform to manage a wide range of infrastructure components on third-party platforms like AWS, GCP, Azure, etc through their APIs.</p>
<p>These infrastructure components could be-</p>
<ul>
<li><p>Compute instances like VMs, etc.</p>
</li>
<li><p>Network infrastructure like DNS, etc.</p>
</li>
<li><p>Monitoring tools like Grafana, Datadog, etc.</p>
</li>
<li><p>Database instances like MySQL, Postgresql, MongoDB, etc.</p>
</li>
<li><p>Version control systems like Github, bitbucket or GitLab.</p>
</li>
</ul>
<p>There are tons of Terraform providers which are publicly available for use. It can be found at terraform registry - <a target="_blank" href="https://registry.terraform.io/search/providers">https://registry.terraform.io/search/providers</a></p>
<p>We will use one of the terraform providers available in this registry for creating a file on the local system. To use terraform, we need to use its language called <strong>HCL</strong>(<strong>Hashicorp configuration language</strong>)</p>
<ul>
<li><p>It is a simple <strong>declarative</strong> language by which we can define infra to be provisioned, <strong>as blocks of code</strong>.<br />  By <strong>declarative,</strong> it means that the code is defined in a way which declares the state we want the infra to be in(i.e. the desired state)</p>
</li>
<li><p>All infra resources can be defined in the configuration file with the <code>.tf</code> extension. The syntax is quite easy and beginner friendly.</p>
</li>
</ul>
<p>Let's create a terraform file in the local system with <code>.tf</code> extension. We will be using the local provider to create a local file for demonstration purposes.</p>
<p>Create a new project directory by name <code>tf-local</code> with the below content -</p>
<pre><code class="lang-bash">provider <span class="hljs-string">"local"</span> {
  // attributes 
}

resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {
    filename=<span class="hljs-string">"./country.txt"</span>
    content=<span class="hljs-string">"My favourite country is India"</span>
}
</code></pre>
<p>This is how a resource to be created is declared in terraform. Let's dissect the above file -</p>
<ul>
<li><p><code>local_file</code> is one of the resources for <code>local</code> <strong>provider.</strong></p>
<ul>
<li>Every object that terraforms manages is called a resource. Resources can be the compute instances, DB instances, or even on-premise or a file on local system as above.</li>
</ul>
</li>
<li><p><code>country</code> is the resource name, which is a logical name given to a resource</p>
</li>
<li><p><code>filename</code> and <code>content</code> are the arguments of the <code>local_file</code> resource.</p>
</li>
</ul>
<blockquote>
<p>Each provider has its own set of resources and each resource has its own set of arguments. These details about the provider can be found in terraform registry itself.</p>
<p>For the local provider used above, you can refer -<a target="_blank" href="https://registry.terraform.io/providers/hashicorp/local/latest/docs">https://registry.terraform.io/providers/hashicorp/local/latest/docs</a></p>
</blockquote>
<p>The above terraform file implies that once it is executed, it should create a file <strong>country.txt</strong> in the local system with content as <code>My favourite country is India</code></p>
<hr />
<p>In any infrastructure, there are 2 <strong>states</strong> -</p>
<ol>
<li><p>Current state - which is the current environment state.</p>
</li>
<li><p>Desired state/target state - which is the environment in which we want our infrastructure to be.</p>
</li>
</ol>
<p>The <strong>state</strong> is the blueprint of the infrastructure deployed by Terraform. Terraform can read attributes of existing infra components by configuring the source. This can be used to later configure other resources within terraform.</p>
<h3 id="heading-terraform-workflow">Terraform workflow</h3>
<p><strong>Terraform takes care of what is required to go from the <em>current state</em> to the <em>desired state</em></strong>. To do this, it works in 3 phases -</p>
<ol>
<li><p><strong>init</strong> - In this phase, terraform initializes the project and identifies and downloads providers to be used for the target/desired environment.</p>
</li>
<li><p><strong>plan</strong> - In this phase, terraform drafts the plan to get to the target state. It tells what will be the consequence of executing the changes(for example- one file will be created).</p>
</li>
<li><p><strong>apply</strong> - In this phase, it makes the necessary changes required in the environment to bring it to the desired/target state.</p>
</li>
</ol>
<h3 id="heading-create-resource">Create resource</h3>
<p>Let's run the terraform commands for the above phases. Go to the <code>tf-local</code> the directory that we created and run the below commands one by one</p>
<pre><code class="lang-bash">terraform init
terraform plan
terraform apply
</code></pre>
<p><strong>Lets understand the output of each of these commands</strong></p>
<p><strong>The output of</strong> <code>terraform init</code> <strong>command -</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675005963024/91b632b6-b399-4e3d-9617-6c5c9335c593.png" alt class="image--center mx-auto" /></p>
<p>It will install the latest version of <code>local</code> provider from the terraform registry.</p>
<p>You can also specify the version specifically if you want to install older ones using the below steps -</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675006820720/b74969a2-ac37-483d-817c-6384080ced05.png" alt class="image--center mx-auto" /></p>
<p><strong>The output of</strong> <code>terraform plan</code> <strong>command -</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675006139474/2e6c12b4-bdd9-44e9-98b3-95d22b8fd6fd.png" alt class="image--center mx-auto" /></p>
<p>As you can see, it drafts the whole plan of what it will do once you apply changes, i.e. a file country.txt will be created with the content as specified in <code>tf</code> file, and with default permission of <code>0777</code> .</p>
<p><strong>The output of</strong> <code>terraform apply</code> <strong>command -</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675006996627/fa9d9d90-dba4-4516-ac1c-e9b16e53c268.png" alt class="image--center mx-auto" /></p>
<p>The above command creates the resource <strong>country.txt</strong> with the specified content. You can verify this by running <code>cat country.txt</code> from the command line.</p>
<h3 id="heading-update-and-destroy-resources"><strong>Update and destroy resources</strong></h3>
<p>Let's update the file permission to <code>0700</code> of the above <code>country.txt</code> file using terraform code changes.</p>
<p>Append the <code>file_permission</code> attribute like shown below in the same <code>local_file</code> <code>country</code> resource in the terraform file.</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {
        filename=<span class="hljs-string">"./country.txt"</span>
        content=<span class="hljs-string">"My favourite country is India"</span>
        file_permission=<span class="hljs-string">"0700"</span> <span class="hljs-comment"># ADDED </span>
}
</code></pre>
<p>Now, let's see the change in terraform state by running the <code>terraform plan</code> command</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675455250970/56edabd6-16fd-4a51-8b8e-397f51010690.png" alt class="image--center mx-auto" /></p>
<p>As you can see it says the file_permission will be replaced from default being <code>0777</code> to the new value <code>0700</code></p>
<p>Let's run the <code>terraform apply</code> command</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675455808433/ed32f3a2-009b-4abe-a8d2-e4e6561d6742.png" alt class="image--center mx-auto" /></p>
<p>In the above screenshot, after running the terraform apply, we can also check the file permission for country.txt by running the command <code>stat country.txt</code>. It rightly signifies the permission(<code>-rwx------</code>) that we wanted it to be in.</p>
<blockquote>
<p>In case you don't have an idea what <code>0700</code> or <code>-rwx------</code> signifies, these are the notations which specify the permissions of a file. To know more about them, I would suggest you go through <a target="_blank" href="https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation:~:text=sticky%20attributes%20set.-,Numeric%20notation,-%5Bedit%5D"><mark>this</mark></a> (<em>symbolic and numeric notation</em>)</p>
</blockquote>
<h3 id="heading-create-multiple-resources"><strong>Create multiple resources</strong></h3>
<p>Terraform allows the creation of multiple resources within the same file by just writing a new block for each resource.</p>
<p>We will add one more resource <code>random_shuffle</code> to the existing terraform file. This resource belongs to <code>random</code> provider (<a target="_blank" href="https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/shuffle">documentation</a> for reference)</p>
<pre><code class="lang-bash">provider <span class="hljs-string">"random"</span> {
  <span class="hljs-comment"># Configuration options</span>
}

resource <span class="hljs-string">"random_shuffle"</span> <span class="hljs-string">"country_shuffle"</span> {
  input        = [<span class="hljs-string">"India"</span>, <span class="hljs-string">"Germany"</span>, <span class="hljs-string">"USA"</span>, <span class="hljs-string">"London"</span>]
  result_count = 1
}
</code></pre>
<p>Now, since we are also adding a new provider, we will need to run through all the lifecycle stages, i.e. <code>init</code>, <code>plan</code> and <code>apply</code></p>
<p>Run the below commands one by one</p>
<pre><code class="lang-bash">terraform init
terraform plan
terraform apply
</code></pre>
<p><code>terraform init</code> - installs the newly added random provider by downloading it from registry</p>
<p><code>terraform plan</code> - signifies that the country_shuffle will be created, and the result will be known once we run the apply command</p>
<p><code>terraform apply</code> - applies the required changes</p>
<p>Once this runs, we can check the <strong>result of country_shuffle</strong> in the <code>terraform.tfstate</code> file created in our directory.</p>
<p>The <code>tfstate</code> file contains the current state of terraform and is updated whenever the state of the environment changes as we add or update any resource</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675495864484/fe799f5d-ac61-4550-a25c-43e8bd557f1c.png" alt class="image--center mx-auto" /></p>
<p>As we can see, it randomly chose the <code>USA</code> value,</p>
<p><strong>We can programmatically capture this output and even pass it to some other resource in our terraform file. This is explained in the below section.</strong></p>
<h3 id="heading-resource-attribute-reference"><strong>Resource attribute reference</strong></h3>
<p>In the real world, it is bound to happen that multiple resources depend on each other. What if we want to use the output of one resource to be an input of other?</p>
<p>This can be done in terraform using <strong>resource attribute reference</strong>.</p>
<p>Let's consider the above example where we want to use the output of <code>random_shuffle</code> resource and provide it in the content of <code>local_file</code> <strong>country</strong> resource</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {
    filename=<span class="hljs-string">"./country.txt"</span>
    content=<span class="hljs-string">"My favourite country is <span class="hljs-variable">${random_shuffle.country_shuffle.result[0]}</span>"</span> <span class="hljs-comment"># UPDATED</span>
    file_permission=<span class="hljs-string">"0700"</span> 
}
</code></pre>
<p>We are updating the content of our <code>local_file</code> country resource with the value retrieved from <code>random_shuffle</code> (<code>country_shuffle</code>) resource output.</p>
<p>With the above changes, terraform automatically understands that the <code>local_file</code> <code>country</code> resource is <strong>dependent</strong> on the <code>random_shuffle</code> resource, so <code>random_shuffle</code> resource needs to be applied first before <code>country</code> resource.</p>
<p>This is called <strong>implicit</strong> <strong>dependency</strong>, as it is understood based on the given reference expression, without our need to tell to terraform explicitly.</p>
<p>Let's run terraform <code>plan</code> and <code>apply</code> after making the above changes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675496737715/18c1dfda-135a-4ca7-a477-ab6da32bc2ec.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675496778263/4930e2b3-326a-46f3-9664-a0e8b56ba000.png" alt class="image--center mx-auto" /></p>
<p>As you can see above, the content was updated as we expected it to be.</p>
<p>Terraform also supports <strong>explicit</strong> dependency where we can provide <code>depends_on</code> attribute like below -</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {   
     content = <span class="hljs-string">"London"</span> 
     depends_on = [ random_shuffle.country_shuffle ] 
}
</code></pre>
<p>This is necessary only when a resource relies on some other resource <strong>indirectly</strong> and it does not make use of any reference expression.</p>
<h3 id="heading-input-variables">Input variables</h3>
<p>We have used arguments till now where the values are directly hard coded in terraform file. Instead of hardcoding values(which may limit reusability), we can also create the input <strong>variables</strong> in Terraform.</p>
<p>To assign variables, let's create new config files <code>variables.tf</code>with the below content.</p>
<pre><code class="lang-bash">variable <span class="hljs-string">"filename"</span> { 
    default = <span class="hljs-string">"/country.txt"</span> 
}
</code></pre>
<p>Now to use it in our main file, we can rename the filename values to <code>var.filename</code></p>
<pre><code class="lang-bash">resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {
    filename=var.filename <span class="hljs-comment"># UPDATED</span>
    content=<span class="hljs-string">"My favourite country is <span class="hljs-variable">${random_shuffle.country_shuffle.result[0]}</span>"</span>
    file_permission=<span class="hljs-string">"0700"</span>
}
</code></pre>
<p>We can also provide the variable <strong>data type</strong> in our variable definition file. This is optional, but when used, it strictly enforces the type of the variable being used, like string, number, bool, etc.</p>
<p>Apart from the above, terraform also supports additional types like lists, maps, objects, etc. Let's see a couple of examples below</p>
<ul>
<li><p><strong>List type:</strong></p>
<pre><code class="lang-bash">  variable <span class="hljs-string">"list_demo"</span> { 
      default = [<span class="hljs-string">"a"</span>,<span class="hljs-string">"b"</span>,<span class="hljs-string">"c"</span>] 
      <span class="hljs-built_in">type</span> = <span class="hljs-string">"list"</span> 
  }
</code></pre>
<p>  We can access var.list_demo[0] in the main terraform file</p>
<p>  We can also enforce the type of values in the list; by specifying the type as <code>list(string)</code> for list values being string type.</p>
</li>
<li><p><strong>Map type:</strong></p>
<pre><code class="lang-bash">  variable <span class="hljs-string">"map_demo"</span> { 
      <span class="hljs-built_in">type</span> = <span class="hljs-string">"map"</span> 
      default = { 
          <span class="hljs-string">"foo"</span> = <span class="hljs-string">"foo content"</span>
          <span class="hljs-string">"bar"</span> = <span class="hljs-string">"bar content"</span> 
      } 
  }
</code></pre>
<p>  Now, we can access this in our main terraform file like <code>var.map_demo["foo"]</code></p>
</li>
<li><p><strong>Object type:</strong></p>
<pre><code class="lang-bash">  variable <span class="hljs-string">"object-demo"</span> { 
      <span class="hljs-built_in">type</span> = object({ 
              name = string 
              age = number
              country = list(string)
      })

      default = { 
          name = <span class="hljs-string">"foo"</span> 
          age = 4 
          country = [<span class="hljs-string">"India"</span>, <span class="hljs-string">"USA"</span>, <span class="hljs-string">"London"</span>] 
      } 
  }
</code></pre>
</li>
</ul>
<hr />
<p>By default, if we don't provide the default values of variables, then we will be prompted in an <strong>interactive</strong> way to provide values while we run <code>terraform plan</code> or <code>terraform apply</code>.</p>
<p>In our example, let's remove the default value for <code>filename</code> variable that we had defined.</p>
<pre><code class="lang-bash">variable <span class="hljs-string">"filename"</span> { 
    <span class="hljs-comment"># default = "./country.txt" # COMMENTED OUT</span>
}
</code></pre>
<p>Now if we run terraform plan, we will be prompted for providing value in CLI like below-</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675500190948/510f7663-273e-4e29-91af-26f291219ead.png" alt class="image--center mx-auto" /></p>
<p>However, if we don't want interactive mode, we can also make use of <strong>cmd flags</strong> like the below <strong>-</strong></p>
<p><code>terraform plan -var "filename=./country.txt" [-var ....]</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675500443463/3e5bbf4d-7532-4a75-8298-e3ad77367941.png" alt class="image--center mx-auto" /></p>
<p>Apart from the above 2 options -</p>
<ul>
<li><p>We can also make use of <strong>env variables</strong></p>
<pre><code class="lang-bash">  ➜ <span class="hljs-built_in">export</span> TF_VAR_filename=<span class="hljs-string">"test.txt"</span> 
  ➜ terraform plan
</code></pre>
<p>  If we set this, then it becomes the <strong>default</strong> value unless we provide some value in the <strong>cmd flag</strong>.</p>
</li>
<li><p>While dealing with lot of variables, we can also <strong>make use of variable definition files</strong> like below</p>
<ul>
<li><p>Create a file with name <code>variables.tfvars</code> and with below content</p>
<pre><code class="lang-bash">  filename = <span class="hljs-string">"test2.txt"</span>
</code></pre>
</li>
<li><p>Now we can provide the file name as a <strong>cmd flag -</strong> <code>terraform plan -var-file variables.tfvars</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675500710604/686be877-3855-4387-8ad5-2bf56a74804b.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-output-variables">Output variables</h3>
<p>These variables can be used to store the value of an expression in terraform.</p>
<p>Let's take an example in our use case, we know country resource will generate some identifier(id) when we run apply command. To save this id, we can create an output block</p>
<pre><code class="lang-bash">output country_id { 
    value = local_file.country.id
    description = <span class="hljs-string">"File resource ID"</span> <span class="hljs-comment"># optional </span>
}
</code></pre>
<p>We can see this output variable once we perform <code>terraform apply</code> like below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675503782295/56abbda3-1d3d-4905-9a4b-f2643f5cbda0.png" alt class="image--center mx-auto" /></p>
<p><strong>Now you may think about where can we use this output variable. 🤔</strong></p>
<p>We can use this when we want to display it on some UI or pipeline or if we want to provide the output as input to some other IaC tool like Ansible, etc.</p>
<p><code>terraform output</code> - Prints all the output variables mentioned in terraform file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675503825752/1e16f3e4-c2b1-4558-9d12-941b56a2cabb.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-lifecycle-rules">Lifecycle rules</h3>
<p>Terraform resources are immutable, which means we cannot update the resource once created.</p>
<p>When we make some updates in the terraform file and try to apply the changes, it deletes the existing resource and then creates a new resource with an updated config. In our case, the older local_file resource is deleted first and then a new file is created.</p>
<p>What if we want to create an updated version first and then delete the old ones? Or if we do not want the older resource to be deleted at all(for use cases like an EC2 instance, etc)? - <strong>We can use lifecycle rules</strong>.</p>
<p>Just add the <code>lifecycle</code> block in the existing local_file <code>country</code> resource block like below</p>
<pre><code class="lang-bash">resource <span class="hljs-string">"local_file"</span> <span class="hljs-string">"country"</span> {
    filename=var.filename
    content=<span class="hljs-string">"My favourite country is <span class="hljs-variable">${random_shuffle.country_shuffle.result[0]}</span>"</span>
    file_permission=<span class="hljs-string">"0700"</span>
    <span class="hljs-comment"># ADDED</span>
    lifecycle { 
        create_before_destroy=<span class="hljs-literal">true</span>  <span class="hljs-comment"># optional</span>
    }
}
</code></pre>
<p><code>create_before_destroy</code> - will create the new resource first and then destroy the older one</p>
<p>There are other <strong>lifecycle meta-attributes</strong> as well which are used vastly like <code>prevent_destroy</code> and <code>ignore_changes</code></p>
<ul>
<li><p><code>prevent_destroy</code> - this won't destroy the old resource while running <code>apply</code> command.</p>
</li>
<li><p><code>ignore_changes</code> - will ignore the changes made outside of terraform, and it won't sync those changes with the terraform state after the initial <code>apply</code>. This is useful in certain cases where the changes are made out of terraform control and we don't want to consider the changes in the terraform reconciliation phase, which will revert them unnecessarily.</p>
</li>
</ul>
<h3 id="heading-data-sources">Data sources</h3>
<p>Terraform is only one of the tools which provide IAC. Infra can be created using other tools like Ansible or even via some ad-hoc scripts or manually created.</p>
<p>Let's say we manually create a new local file in the local directory <code>food.txt</code> without terraform knowing about it. We would like the terraform to know about this and use this file as a data source for the other terraform resources. This can be done via the data source.</p>
<p>Just manually create a <code>food.txt</code> file and add <code>Pizza</code> in this file content.</p>
<p>Now, add the below in the main terraform file-</p>
<pre><code class="lang-bash">data <span class="hljs-string">"local_file"</span> <span class="hljs-string">"food"</span> {
    filename = <span class="hljs-string">"./food.txt"</span>
}
</code></pre>
<p>In the <code>country</code> resource, we can feed the content of this <code>food.txt</code> in our content of <code>country</code> resource file</p>
<p>Just update the content value of the <code>country</code> resource as below</p>
<pre><code class="lang-bash">content=<span class="hljs-string">"My favourite country is <span class="hljs-variable">${random_shuffle.country_shuffle.result[0]}</span>, and favourite food is <span class="hljs-variable">${data.local_file.food.content}</span>"</span>
</code></pre>
<p>Now, run the <code>plan</code> and <code>apply</code> command, and then check the test.txt file - the output will be as expected as shared below -</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675514765709/527ef927-6124-4c1e-bb16-b97b4158f60c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-other-useful-commands">Other useful commands</h3>
<ul>
<li><p><code>terraform validate</code> - Checks if the terraform config is valid or not.</p>
</li>
<li><p><code>terraform fmt</code> - Scans the config files and formats the code into the canonical format to improve readability<br />  The above two commands can be run before <code>terraform plan</code> and is mostly used in the <strong><em>build</em></strong> or <strong><em>verification</em></strong> phases of the CI/CD lifecycle.</p>
</li>
<li><p><code>terraform show</code> - Displays the current state of resources including all attributes created by terraform for that resources</p>
</li>
<li><p><code>terraform output</code> - Prints all the output variables mentioned in terraform file.</p>
</li>
<li><p><code>terraform refresh</code> - Used to sync terraform with real-world infra.<br />  This is useful in case there are any changes made to a terraform resource outside its control(like a manual update). In such cases, terraform will pick it up and update the state file. This reconciliation will determine what action to take during the next applied command. Note that this command is automatically run when we run the plan and apply commands</p>
</li>
<li><p><code>terraform destroy</code> - Destroys the terraform resources mentioned in the terraform file.</p>
</li>
</ul>
<hr />
<p><strong>That's it for this article.</strong></p>
<p><strong>🚀 I have also pushed the example code explained in this article to</strong> <a target="_blank" href="https://github.com/hax0rr/terraform-local"><strong>Github</strong></a><strong>.</strong></p>
<p>If you found this article helpful, please comment and share this article 😃.</p>
<p>Let's connect 💫</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>You can also subscribe to my newsletter below to get an email notification on my latest posts. 💻</p>
]]></content:encoded></item><item><title><![CDATA[Redis Data Structures]]></title><description><![CDATA[Redis is an in-memory database which has a very powerful set of data types and data structures. These data structures are used across a variety of applications like message queues, game leaderboards, etc. Redis has been widely popular because of its ...]]></description><link>https://neelvikmani.hashnode.dev/redis-data-structures</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/redis-data-structures</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[software development]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Redis]]></category><category><![CDATA[WeMakeDevs]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Sun, 29 Jan 2023 15:03:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674222796828/3a15792b-93cd-4271-ad06-bf2b732e7def.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Redis is an in-memory database which has a very powerful set of data types and data structures. These data structures are used across a variety of applications like message queues, game leaderboards, etc. Redis has been widely popular because of its performance efficiency and simplicity of using it.</p>
<p>In this article, I have explained the most commonly used data types in Redis with examples.</p>
<p>I would also recommend installing Redis on your local machine and following this article by actually executing the commands hands-on. Once you install Redis(instructions <a target="_blank" href="https://redis.io/docs/getting-started/installation/"><em>here</em></a><em>)</em>, run <code>redis-cli</code> command from your CLI, this will open the command line interface of redis where you can run the commands which are mentioned below in this article.</p>
<p><strong>Before starting with Redis data types, let's understand what are the keys in Redis</strong></p>
<h2 id="heading-keys">Keys</h2>
<p>Keys are the primary way to access data in Redis. Almost all the Redis data structures and Redis commands operate using keys.</p>
<p>Usually, it is suggested to have a meaningful domain-specific key name, with a separator if required; for example: <code>product:12</code> may be used for storing details about a product which has a primary id 12.</p>
<p>Keys are used in almost all data types of Redis like string, list, hashes, sets, etc.</p>
<p>We will now start with a String data type to also get acquainted with keys.</p>
<h2 id="heading-strings">Strings</h2>
<p>We will be exploring the below commands which are applied for string data type -</p>
<pre><code class="lang-bash">SET &lt;key&gt; &lt;value&gt;  
GET &lt;key&gt;
KEYS &lt;regex pattern&gt;
SCAN &lt;cursor&gt;
DEL &lt;key&gt; 
UNLINK &lt;key&gt;
EXISTS &lt;key&gt;
</code></pre>
<ul>
<li><p><code>SET &lt;key&gt; &lt;value&gt;</code> - sets the value of the given key</p>
<ul>
<li><p>You can also provide the expiry of this key using <strong>EX</strong> or <strong>EXAT</strong> argument.</p>
</li>
<li><p>By default, if the key is not present, it will create the key, else it will update the value of the key. If you want to SET the key only if the key does not already exist, then you can pass the <strong>NX</strong> argument.</p>
</li>
</ul>
</li>
<li><p><code>GET &lt;key&gt;</code> - returns the value of the given key name. ex: <code>GET product:12</code></p>
</li>
<li><p><code>MGET &lt;key&gt; [&lt;key&gt;...]</code> - returns the value of multiple keys passed in the argument</p>
<p>  Below is the demonstration in redis-cli :</p>
<pre><code class="lang-bash">  <span class="hljs-comment"># Sets the value as product-12-value with expity of 2 mins</span>
  127.0.0.1:6379&gt; SET product:12 product-12-value EX 120 NX
  <span class="hljs-comment"># OUTPUT</span>
  OK

  127.0.0.1:6379&gt; SET product:13 p13
  <span class="hljs-comment"># OUTPUT</span>
  OK

  127.0.0.1:6379&gt; get product:12
  <span class="hljs-comment"># OUTPUT</span>
  <span class="hljs-string">"product-12-value"</span>

  127.0.0.1:6379&gt; GET product:12
  <span class="hljs-comment"># OUTPUT</span>
  <span class="hljs-string">"product-12-value"</span>

  127.0.0.1:6379&gt; MGET product:12 product:13
  <span class="hljs-comment"># OUTPUT</span>
  1) <span class="hljs-string">"product-12-value"</span>
  2) <span class="hljs-string">"p13"</span>
</code></pre>
</li>
</ul>
<p>Redis also provides commands to retrieve all the keys in the database matching a regex pattern</p>
<ul>
<li><p><code>KEYS &lt;regex pattern&gt;</code> - returns all the keys matching the specified pattern.</p>
<ul>
<li><p>This command is <strong>not recommended</strong> in production applications since it's a blocking command, and it may cause performance issues in the case of large datasets.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; KEYS product:*
  <span class="hljs-comment"># OUTPUT</span>
  1) <span class="hljs-string">"product:12"</span>
  2) <span class="hljs-string">"product:13"</span>
</code></pre>
</li>
</ul>
</li>
<li><p><code>SCAN &lt;cursor&gt; [MATCH pattern] [COUNT count]</code></p>
<ul>
<li><p>This command also blocks the thread but it returns only a few keys at a time, along with a cursor. You need to call <code>SCAN 0</code><em>(0 is the cursor here)</em> for the first time and then iteratively call the SCAN command with the updated cursor which was returned in the response.</p>
</li>
<li><p>When the server response has the cursor value as 0, it signifies no other keys left to iterate, so you can stop the iteration at this point.</p>
</li>
<li><p>The user can also specify an optional MATCH argument to retrieve based on a specified regex pattern, and a COUNT argument signifying what number of keys to be retrieved per SCAN, though this can block the thread longer if the COUNT value is too large.</p>
</li>
</ul>
</li>
</ul>
<p>To delete the key, Redis provides 2 commands</p>
<ul>
<li><p><code>DEL &lt;key&gt;</code> - deletes the key in a blocking manner</p>
</li>
<li><p><code>UNLINK &lt;key&gt;</code> - deletes the key in a non-blocking way, where the memory associated with the key is reclaimed by an asynchronous process.</p>
</li>
</ul>
<p>You can also check if the key exists or not using <code>EXISTS &lt;key&gt;</code> command.</p>
<p>Apart from <code>keys</code> and <code>scan</code> command, all other commands have a time complexity of O(1). Every scan command is O(1), but it can become O(N) for complete iteration.</p>
<hr />
<p>Strings are fundamental data types in Redis and can be used to store numerical values, serialized JSON or anything that case which can be represented in binary. All the commands we saw above are used for strings.</p>
<p>🚨 Even if you run <code>SET int-key 12</code>, and then try to GET the value, it will return value <strong>12</strong> as a <strong>string</strong>.</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; SET int-key 12
OK

127.0.0.1:6379&gt; GET int-key
<span class="hljs-string">"12"</span>
</code></pre>
<p>You can check the type of key using <code>type &lt;key&gt;</code> command. For the above key, it will return a string.</p>
<p>This is because it returns the string representation of the value. The different types that can be returned are: <em>string, list, set, zset, hash and stream</em> (We will look into these types below)</p>
<p>Internally, Redis stores the encoding of the values, and stores the knowledge whether it's a string, integer, floating number, etc. To check the kind of internal representation used to store the value, you need to use <code>object encoding &lt;key&gt;</code>. This command will return "<strong>int</strong>" as a value as shown below.</p>
<pre><code class="lang-bash">127.0.0.1:6379&gt; TYPE int-key
string

127.0.0.1:6379&gt; OBJECT ENCODING int-key
<span class="hljs-string">"int</span>
</code></pre>
<p>For numeric values, we can also increment/decrement the value directly using the below Redis commands:</p>
<ul>
<li><p><code>INCR/DECR &lt;key&gt;</code> - increments/decrements the key value by 1</p>
</li>
<li><p><code>INCRBY/DECRBY &lt;key&gt; &lt;increment value&gt;</code> - increments/decrements by the specified increment value</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; INCR int-key
  (<span class="hljs-built_in">integer</span>) 13

  127.0.0.1:6379&gt; INCR int-key
  (<span class="hljs-built_in">integer</span>) 14

  127.0.0.1:6379&gt; GET int-key
  <span class="hljs-string">"14"</span>
</code></pre>
</li>
</ul>
<p><strong>Use cases of Strings:</strong></p>
<ul>
<li><p>Caching the API response in JSON string format. for example: <code>SET product:12 "{\"name\":\"P1\",\"price\":\"121\"}"</code></p>
</li>
<li><p>Storing session cache.</p>
</li>
</ul>
<h2 id="heading-hashes">Hashes</h2>
<p>Hashes are a collection of field-value pairs, similar to hashmaps or maps in other languages like Java, Go, etc. They are mutable as well, so we can update or delete the hash and even add/update the field-value pairs.</p>
<p>Hashes store field values as string type, which means we can store flat string and numeric values but not embedded JSON or objects.</p>
<p>Similar to Key and string, we have below commands used for hashes -</p>
<ul>
<li><p><code>HSET &lt;key&gt; &lt;field&gt; &lt;value&gt; [&lt;field&gt; &lt;value&gt; ...]</code> - sets/creates or updates the hash with given field-values stored at key</p>
<ul>
<li><p><code>HSET hash-example:product:12  name p1 price 22</code> will create the hash with key <code>hash-example:product:12</code> for the first time with given fields <code>name</code> and <code>price</code> with their values <code>p1</code> and <code>22</code> respectively.</p>
</li>
<li><p><code>HSET hash-example:product:12 name p12</code> will update the above hash's "name" field's value to <code>p12</code></p>
</li>
</ul>
</li>
<li><p><code>HGET &lt;key&gt; &lt;field&gt;</code> - returns provided field's value from the given hash name</p>
<ul>
<li>Example: <code>HGET hash-example:product:12 name</code> will return <code>p1</code></li>
</ul>
</li>
<li><p><code>HMGET &lt;key&gt; &lt;field&gt; [&lt;field&gt;...]</code> - allows retrieving multiple fields values</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; HSET hash-example:product:12 name p1 price 22
  (<span class="hljs-built_in">integer</span>) 0

  127.0.0.1:6379&gt; HMGET hash-example:product:12 name price
  1) <span class="hljs-string">"p1"</span>
  2) <span class="hljs-string">"22"</span>

  127.0.0.1:6379&gt; HSET hash-example:product:12 name p2
  (<span class="hljs-built_in">integer</span>) 0

  127.0.0.1:6379&gt; HMGET hash-example:product:12 name price
  1) <span class="hljs-string">"p2"</span>
  2) <span class="hljs-string">"22"</span>
</code></pre>
</li>
<li><p><code>HGETALL &lt;key&gt;</code> - will retrieve all the fields with their values for provided key</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; HGETALL hash-example:product:12
  1) <span class="hljs-string">"price"</span>
  2) <span class="hljs-string">"22"</span>
  3) <span class="hljs-string">"name"</span>
  4) <span class="hljs-string">"p2"</span>
</code></pre>
</li>
<li><p><code>HKEYS &lt;key&gt;</code> - will only return the field names for a given hash</p>
</li>
<li><p><code>HLEN &lt;key&gt;</code> - returns the total length(number of fields) of hash</p>
</li>
<li><p><code>HDEL &lt;key&gt;</code>- deletes the hash stored at the given key</p>
</li>
<li><p><code>HINCRBY &lt;key&gt; &lt;field&gt; &lt;incr-value&gt;</code> - will increment the value of the field by <code>incr-value</code> provided in the argument.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; HINCRBY hash-example:product:12 price 2
  (<span class="hljs-built_in">integer</span>) 24

  127.0.0.1:6379&gt; HMGET hash-example:product:12 name price
  1) <span class="hljs-string">"p2"</span>
  2) <span class="hljs-string">"24"</span>
</code></pre>
</li>
<li><p><code>HSCAN &lt;key&gt; &lt;cursor&gt; [MATCH pattern] [COUNT count]</code> - Similar to <code>SCAN</code> command we saw above in the key section, but HSCAN is for scanning hashes.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; hscan hash-example:product:12 0
  1) <span class="hljs-string">"0"</span>
  2) 1) <span class="hljs-string">"price"</span>
     2) <span class="hljs-string">"24"</span>
     3) <span class="hljs-string">"name"</span>
     4) <span class="hljs-string">"p2"</span>
</code></pre>
</li>
</ul>
<p>Apart from <code>HSCAN</code>, <code>HKEYS</code> and <code>HGETALL</code> all other commands have a time complexity of O(1).</p>
<p><strong>Hashes use cases:</strong></p>
<ul>
<li><p>Caching in case the object is too large and we want to only retrieve certain fields instead of all.</p>
</li>
<li><p>Storing User profiles, product information, etc.</p>
</li>
</ul>
<h2 id="heading-list">List</h2>
<p>The list is the sequence of strings, similar to Array or ArrayList in Java, Go, etc. Lists are used for storing arrays of strings, but they can also be used as a stack and queue.</p>
<p>Think of it as a list having a head as left(1st element)and a tail as right(last element). The beauty of this data type is that Redis provide commands to insert and remove the element from both the left and right of the list out of the box, making it ideal for stack and queue use-case implementations.</p>
<p>The list has below list of commands-</p>
<ul>
<li><p><code>LPUSH &lt;key&gt; &lt;element&gt; [&lt;element&gt;...]</code> - is used to insert an element at the head of the list (left push) stored at the key. Multiple elements can also be passed.</p>
<ul>
<li><code>LPUSH demo-list 1 2 3</code> will result in a list with value <code>[3,2,1]</code></li>
</ul>
</li>
<li><p><code>LPOP &lt;key&gt; &lt;count&gt;</code> - is used to remove the data from the head of the list (left pop). Multiple elements can also be removed at once by providing an optional count value</p>
<ul>
<li><code>LPOP demo-list 1</code> will remove the <code>3</code> from the above list; updated list - <code>[2,1]</code></li>
</ul>
</li>
<li><p><code>RPUSH &lt;key&gt; &lt;element&gt; [&lt;element&gt;...]</code> - same as LPUSH, but is used to insert the element or multiple elements at the tail of the list (right push)</p>
<ul>
<li><code>RPUSH demo-list 4 5</code> will add to the above list from the right; updated list - <code>[2,1,4,5]</code></li>
</ul>
</li>
<li><p><code>RPOP &lt;key&gt; &lt;count&gt;</code> - same as LPOP, but is used to remove the data from the tail of the list (right pop)</p>
<ul>
<li><code>RPOP demo-list 1</code> will remove the <code>5</code> from the above list; updated list - <code>[2,1,4]</code></li>
</ul>
</li>
<li><p><code>LRANGE &lt;key&gt; &lt;start&gt; &lt;stop&gt;</code> - returns the elements of the list stored at the key. Start and stop are zero-based indexes, where the start <code>0</code> is the 1st element(head) and so on.</p>
<ul>
<li><p><code>LRANGE demo-list 0 -1</code> will retrieve all elements of the list</p>
</li>
<li><p><code>LRANGE demo-list 0 -2</code> will retrieve all elements from the 1st element till 2nd last element of the list</p>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-bash">127.0.0.1:6379&gt; LPUSH demo-list 1 2 3
(<span class="hljs-built_in">integer</span>) 3

127.0.0.1:6379&gt; LRANGE demo-list 0 -1
1) <span class="hljs-string">"3"</span>
2) <span class="hljs-string">"2"</span>
3) <span class="hljs-string">"1"</span>

127.0.0.1:6379&gt; LPOP demo-list 1
1) <span class="hljs-string">"3"</span>

127.0.0.1:6379&gt; LRANGE demo-list 0 -1
1) <span class="hljs-string">"2"</span>
2) <span class="hljs-string">"1"</span>

127.0.0.1:6379&gt; RPUSH demo-list 4 5
(<span class="hljs-built_in">integer</span>) 4

127.0.0.1:6379&gt; LRANGE demo-list 0 -1
1) <span class="hljs-string">"2"</span>
2) <span class="hljs-string">"1"</span>
3) <span class="hljs-string">"4"</span>
4) <span class="hljs-string">"5"</span>

127.0.0.1:6379&gt; RPOP demo-list 1
1) <span class="hljs-string">"5"</span>

127.0.0.1:6379&gt; LRANGE demo-list 0 -1
1) <span class="hljs-string">"2"</span>
2) <span class="hljs-string">"1"</span>
3) <span class="hljs-string">"4"</span>
</code></pre>
<ul>
<li><p><code>LLEN &lt;key&gt;</code> - returns the length of the list</p>
</li>
<li><p><code>LTRIM &lt;key&gt; &lt;start&gt; &lt;stop&gt;</code> - trims the element and keeps only elements from the specified start index to the stop index in the list.</p>
</li>
</ul>
<p>💫 You can use a combination of the above commands for stack and queue implementations</p>
<ul>
<li><p>For queues, use <code>RPUSH</code> and <code>LPOP</code></p>
</li>
<li><p>For stack, use <code>LPUSH</code> and <code>LPOP</code></p>
</li>
</ul>
<p><strong>List use cases:</strong></p>
<ul>
<li><p>Stack or queue implementations like a queue-based worker.</p>
</li>
<li><p>Social networking sites display only the top 5 trending results, etc.</p>
</li>
</ul>
<h2 id="heading-set">Set</h2>
<p>Set are similar to lists, i.e. an unordered sequence of strings, but the difference is the set does not have duplicate elements, even if you try to insert the same element thousand times. Another difference is that the set does not allow insertions or deletions from the head or tail of the array, since it's not an array, it's just a set!</p>
<p>Redis Set also supports standard mathematical set operations like <strong>Union, Intersection</strong> and <strong>Difference 💫</strong>.</p>
<p>The set has below list of commands-</p>
<ul>
<li><p><code>SADD &lt;key&gt; &lt;member&gt; [&lt;member&gt;...]</code> - Adds the member or members passed in the argument to the set stored at key</p>
<ul>
<li><code>SADD demo-set a b</code> - adds a and b members to the set</li>
</ul>
</li>
<li><p><code>SCARD &lt;key&gt;</code> - returns the cardinality(total number of members) of the set. i.e. 2</p>
</li>
<li><p><code>SISMEMBER &lt;key&gt; &lt;member&gt;</code> - tells whether the given member is part of the set stored at key or not; return 0 if it is not part of the set</p>
<ul>
<li><code>SISMEMBER demo-set bxya</code> - returns 0 as <code>bxya</code> member is not present in set</li>
</ul>
</li>
<li><p><code>SINTER &lt;key&gt; [&lt;key&gt;...]</code> - returns the intersection, i.e. common members between all the sets stored at the provided keys. The time complexity of this command will be <code>O(N*M)</code> where <code>N</code> is the cardinality of the smallest set and <code>M</code> is the total number of sets to compare with.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; SADD demo-set a b
  (<span class="hljs-built_in">integer</span>) 0

  127.0.0.1:6379&gt;  SCARD demo-set
  (<span class="hljs-built_in">integer</span>) 2

  127.0.0.1:6379&gt; SISMEMBER demo-set x
  (<span class="hljs-built_in">integer</span>) 0

  127.0.0.1:6379&gt; SISMEMBER demo-set a
  (<span class="hljs-built_in">integer</span>) 1

  127.0.0.1:6379&gt; SADD demo-set1 a c d
  (<span class="hljs-built_in">integer</span>) 0

  127.0.0.1:6379&gt; SINTER demo-set demo-set1
  1) <span class="hljs-string">"a"</span>
</code></pre>
</li>
<li><p><code>SUNION &lt;key&gt; [&lt;key&gt;...]</code> - - returns the union, i.e. all members in all the given sets stored at the provided keys</p>
<ul>
<li><code>SUNION demo-set demo-set1</code> will return <code>b, c, d, a</code> as the output</li>
</ul>
</li>
<li><p><code>SDIFF &lt;key&gt; [&lt;key&gt;...]</code> - returns the members of the set resulting from the difference between the first set and all the successive sets.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; SUNION demo-set demo-set1
  1) <span class="hljs-string">"b"</span>
  2) <span class="hljs-string">"c"</span>
  3) <span class="hljs-string">"d"</span>
  4) <span class="hljs-string">"a"</span>

  127.0.0.1:6379&gt; SDIFF demo-set demo-set1
  1) <span class="hljs-string">"b"</span>
</code></pre>
</li>
<li><p><code>SMEMBERS key</code> - returns all the members of the set stored at key</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; SMEMBERS demo-set
  1) <span class="hljs-string">"b"</span>
  2) <span class="hljs-string">"a"</span>
</code></pre>
</li>
<li><p><code>SSCAN &lt;cursor&gt; [MATCH pattern] [COUNT count]</code> - Similar to <code>SCAN</code> and <code>HSCAN</code> we saw in the above sections, but <code>SSCAN</code> is used for scanning through sets, and is preferred over <code>SMEMBERS</code> for performance reasons.</p>
</li>
<li><p><code>SREM &lt;key&gt; &lt;member&gt;</code> - removes the specified member from the set</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; sscan demo-set 0
  1) <span class="hljs-string">"0"</span>
  2) 1) <span class="hljs-string">"b"</span>
     2) <span class="hljs-string">"a"</span>

  127.0.0.1:6379&gt; srem demo-set a
  (<span class="hljs-built_in">integer</span>) 1

  127.0.0.1:6379&gt; sscan demo-set 0
  1) <span class="hljs-string">"0"</span>
  2) 1) <span class="hljs-string">"b"</span>
</code></pre>
</li>
</ul>
<p><strong>Set use cases:</strong></p>
<ul>
<li><p>Track unique website visitors based on IP, since sets have deduplication.</p>
</li>
<li><p>The union, intersection and difference make it ideal for use cases where we want to find the commonality or combination of sets between multiple domain data which might have the same members, like for example: to find out all the customers who purchased X as well as Y book. We can have two sets <code>purchase-order:book:X:customers</code> and <code>purchase-order:book:Y:customers</code> whose values are set of customer ids, and we can simply do <code>SINTER</code> to find out users who bought both books.</p>
</li>
</ul>
<h2 id="heading-sorted-set">Sorted Set</h2>
<p>Sorted sets are similar to the sets we discussed above, with an additional property - <strong>a score is associated with each member in the set</strong>. This is a floating point number by which we can specify a sorting order of the members in a sorted set(like sort ascending by score or sort descending by score)</p>
<p>There can be two elements with the same score, in such cases, precedence will be given to a higher member key with a lexical value. example: a sorted set with key <code>ab</code> will be given higher precedence over sorted set with key name <code>bc</code> if both have the same score.</p>
<p>Sorted sets also support <strong>union</strong> and <strong>intersection</strong> commands similar to sets.</p>
<p>The sorted set has a similar list of commands as the set, with an additional <strong>score</strong> value.</p>
<p><strong>Use case</strong>: Let's take a use case of players playing in a tennis tournament and earning some scores. We will add 4 players (player1, player2, player3 and player4) along with their total scores in the tournament</p>
<ul>
<li><p><code>ZADD &lt;key&gt; &lt;score&gt; &lt;member&gt; [&lt;score&gt; &lt;member&gt;...]</code> - adds one more member to the sorted set along with its associated score.</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; zadd game:tennis NX 2 player1
  (<span class="hljs-built_in">integer</span>) 1

  127.0.0.1:6379&gt; zadd game:tennis NX 4 player2
  (<span class="hljs-built_in">integer</span>) 1

  127.0.0.1:6379&gt; zadd game:tennis NX 1 player3
  (<span class="hljs-built_in">integer</span>) 1

  127.0.0.1:6379&gt; zadd game:tennis NX 7 player4
  (<span class="hljs-built_in">integer</span>) 1
</code></pre>
</li>
<li><p><code>ZINCRBY &lt;key&gt; &lt;increment&gt; &lt;member&gt;</code> - increments the score of the member by the values provided in the argument</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; zincrby game:tennis 2 player3
  <span class="hljs-string">"3"</span>
</code></pre>
</li>
<li><p><code>ZRANGE &lt;key&gt; &lt;min&gt; &lt;max&gt; [LIMIT offset count] [WITHSCORES]</code>- retrieves the set members from specified min and max index. You can also pass an optional limit argument to limit the number of returned set members.<br />  <code>WITHSCORES</code> argument will also return the scores of the returned members</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; zrange game:tennis 0 -1 withscores
  1) <span class="hljs-string">"player3"</span>
  2) <span class="hljs-string">"1"</span>
  3) <span class="hljs-string">"player1"</span>
  4) <span class="hljs-string">"2"</span>
  5) <span class="hljs-string">"player2"</span>
  6) <span class="hljs-string">"4"</span>
  7) <span class="hljs-string">"player4"</span>
  8) <span class="hljs-string">"7"</span>
</code></pre>
</li>
<li><p><code>ZRANGEBYSCORE &lt;key&gt; &lt;min&gt; &lt;max&gt; [WITHSCORES] [LIMIT offset count]</code> - returns the members of the set in the order sorted ascending based on score. <strong>Do note</strong> here that the min and max are not zero-based indexes, instead, it starts with 1.</p>
<ul>
<li><p>This can be used to show the leaderboards of players, for example: to show the bottom 3 players(which have the lowest score) <code>ZRANGEBYSCORE game:tennis 1 4</code></p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; ZRANGEBYSCORE game:tennis 1 4 WITHSCORES
  1) <span class="hljs-string">"player3"</span>
  2) <span class="hljs-string">"1"</span>
  3) <span class="hljs-string">"player1"</span>
  4) <span class="hljs-string">"2"</span>
  5) <span class="hljs-string">"player2"</span>
  6) <span class="hljs-string">"4"</span>
</code></pre>
</li>
</ul>
</li>
<li><p><code>ZSCORE &lt;key&gt; &lt;member&gt;</code> - returns the score of the specified member</p>
</li>
<li><p><code>ZREVRANGEBYSCORE &lt;key&gt; &lt;min&gt; &lt;max&gt; [WITHSCORES] [LIMIT offset count]</code> - similar to <code>ZRANGEBYSCORE</code> mentioned above but this command will return based on descending order of the score</p>
<ul>
<li><p>This can be used to show the tournament leaderboard, for example: to show the top 3 players(which has the highest score)</p>
<pre><code class="lang-bash">  127.0.0.1:6379&gt; ZREVRANGEBYSCORE game:tennis +inf -inf WITHSCORES LIMIT 0 3
  1) <span class="hljs-string">"player4"</span>
  2) <span class="hljs-string">"7"</span>
  3) <span class="hljs-string">"player2"</span>
  4) <span class="hljs-string">"4"</span>
  5) <span class="hljs-string">"player1"</span>
  6) <span class="hljs-string">"2"</span>
</code></pre>
</li>
</ul>
</li>
<li><p><code>ZRANK &lt;key&gt; &lt;member&gt;</code> - returns the rank of the user based on ascending order of scores. Note that rank is zero-based, which means that the member with the lowest score has rank <code>0</code>.</p>
</li>
<li><p><code>ZREVRANK &lt;key&gt; &lt;member&gt;</code> - returns the rank of the user based on descending order of scores. The member with the highest score will have the lowest rank(i.e. rank 0)</p>
<ul>
<li>This can be used to display the rank of individual players</li>
</ul>
</li>
<li><p><code>ZREMRANGEBYRANK &lt;key&gt; &lt;start&gt; &lt;stop&gt;</code> - removes the members from the set with the rank range specified in the argument. For example: to retain only the top 3 players in the leaderboard and remove others, we can run -</p>
<pre><code class="lang-bash">  <span class="hljs-comment"># Since the ZREMRANGEBYRANK will evaluate based on scores sorted in ascending order, we will want to retain only bottom 3 elements(which are actually top 3 players by rank, so we will remove from 1st element(index 0) till fourth last element(index -4), hence retaining the top 3 players)</span>
  127.0.0.1:6379&gt; ZREMRANGEBYRANK game:tennis 0 -4
  (<span class="hljs-built_in">integer</span>) 1 

  127.0.0.1:6379&gt; ZREVRANGEBYSCORE game:tennis +inf -inf WITHSCORES LIMIT 0 10
  1) <span class="hljs-string">"player4"</span>
  2) <span class="hljs-string">"7"</span>
  3) <span class="hljs-string">"player2"</span>
  4) <span class="hljs-string">"4"</span>
  5) <span class="hljs-string">"player1"</span>
  6) <span class="hljs-string">"2"</span>
</code></pre>
</li>
<li><p><code>ZUNION &lt;numkeys&gt; &lt;key&gt; [&lt;key&gt;..] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]</code></p>
<ul>
<li><p>This performs a union on total N(numkeys) keys specified in the argument and returns the result. <code>WITHSCORES</code> is an optional argument by which scores will also be passed in the result.</p>
</li>
<li><p><strong>Note</strong>: By default, if a key is present in two sets, the <code>ZUNION</code> will add the scores in both sets and return the new score. If we don't want to add up the score, we can also pass <code>AGGREGATE</code> function arguments like <code>MIN</code> or <code>MAX</code></p>
</li>
</ul>
</li>
<li><p><code>ZINTER &lt;numkeys&gt; &lt;key&gt; [&lt;key&gt;..] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]</code></p>
</li>
<li><p><code>ZSCAN &lt;cursor&gt; [MATCH pattern] [COUNT count]</code> - Similar to <code>HSCAN</code> and <code>SSCAN</code> mentioned above, but ZSCAN is used to scan over sorted sets.</p>
</li>
</ul>
<p><strong>Sorted sets use cases:</strong></p>
<p>Since sorted sets have a score associated with each member and an extensive set of commands to play on this score, it makes it ideal for use cases like -</p>
<ul>
<li><p>Priority queues / task scheduling service</p>
</li>
<li><p>Game Leaderboards</p>
</li>
<li><p>Geo hashing</p>
</li>
</ul>
<hr />
<p>There are other Redis data structures as well like Bitmaps, Geospatial, and HyperLogLog which I will try to cover in some other article. The ones mentioned in this article are the most basic and commonly used Redis data types and data structures.</p>
<h2 id="heading-few-more-facts-about-redis">Few more facts about Redis 💡</h2>
<p>Redis being an in-memory database leverages several efficient low-level data structures without worrying about how to persist them effectively.</p>
<p>Redis is <strong>single threaded</strong> hence it does not have to deal with locks and other synchronization mechanisms, making it simpler to use and think of for your system design.</p>
<p>Redis is known for its fast performance, although it is single-threaded. It is because Redis supports <strong>I/O multiplexing</strong> where the operating system allows a single thread to wait on multiple socket connections. Because of this, Redis still accepts a large number of requests concurrently and evaluates them one by one. This evaluation/execution phase is extremely fast because it is an in-memory data store. Applications using Redis are usually I/O heavy and I/O takes time whereas in-memory operations are extremely fast, so with I/O multiplexing, redis can support a large number of TCP connections while being extremely fast at executing the memory operations.</p>
<p>Redis also supports transactions and an optimistic locking mechanism. I will be making a separate article for the same. 😉</p>
<h2 id="heading-what-to-do-after-reading-this-article">What to do after reading this article</h2>
<p>Well, since now you know the basics of Redis data structures, you can build a small project using Java, Go, Ruby or any other language and use Redis as a data store.</p>
<p>Few projects ideas where you can use the above data structures -</p>
<ol>
<li><p>Sports event</p>
</li>
<li><p>Product Catalog</p>
</li>
<li><p>Library management</p>
</li>
</ol>
<p>Do comment down if you have more project ideas to work on.</p>
<p>If you found this article helpful, please comment and share this article 😃.</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>You can also subscribe to my newsletter below to get an email notification on my latest posts. 💻</p>
]]></content:encoded></item><item><title><![CDATA[Basics of Docker: Why, What and How]]></title><description><![CDATA[Before directly learning about docker, let's build an understanding of basics, like what is a container, what problem it solves and why we need docker. Then we will see how to build docker images and containers and which docker commands are most comm...]]></description><link>https://neelvikmani.hashnode.dev/basics-of-docker-why-what-and-how</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/basics-of-docker-why-what-and-how</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Sat, 21 Jan 2023 06:55:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673946950481/e0f1e8b7-f86e-413d-a940-ffc880e3edac.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before directly learning about docker, let's build an understanding of basics, like what is a container, what problem it solves and why we need docker. Then we will see how to build docker images and containers and which docker commands are most commonly used in the usual day-to-day work.</p>
<h2 id="heading-problem">Problem</h2>
<p>One of the issues developers face is that the software or project they build works seamlessly on one machine but fails to work on another machine. There could be an issue with the package version mismatch used in the project or some difference in the machine architecture between two different machines. The famous dialogue "<strong><em>It works on my machine</em></strong>" comes into the picture here!</p>
<p>To solve this, you may think of starting a Virtual Machine locally using VirtualBox or VMWare, but the problem here is that a VM requires a new operating system on its own on top of the physical machine and requires a dedicated amount of hard disk, CPU and memory for itself. This is not much performant, as the resources would be wasted if not used by the virtual machine. 🤯</p>
<p>So we need something which can run on the same OS as the host machine without the overhead of installing another layer of OS or having dedicated hardware configurations.</p>
<h2 id="heading-solution"><strong>Solution 💡</strong></h2>
<p>Containers solve both these problems. Instead of dividing the hardware resources for the different operating systems and VMs, containers run all the application code along with its dependencies like programming and environment runtimes in an independent environment built over the same operating system.</p>
<p>The container runs in isolation from its host machine, hence it can still support and have the required versions of packages for running the application seamlessly. These packages and required dependencies inside the container won't interfere with the versions of the packages or dependencies which are present in the host machine.</p>
<p>As a developer, we need some platform or some tool via which we can create, build and manage these containers.</p>
<h3 id="heading-this-is-where-docker-comes-into-the-picture"><strong>This is where Docker comes into the picture🐬</strong></h3>
<p>Docker is one of the platforms which enables us to create, build and run the required applications inside containers.</p>
<p>Docker provides various constructs and commands by which we can bundle the required dependencies or packages together and run them in a container which is isolated from the host machine.</p>
<p>Docker has something known as <strong>images</strong> which are similar to <strong>snapshots in a VM</strong>, i.e. it contains all the instructions required to run the application inside the container.</p>
<p>We can run these images, which will execute those instructions inside a container. We can also say that the container is just a <em>runtime instance</em> of the docker image.</p>
<p>So in short, we need to first build these docker images and then run the images inside the container. Running the images will create the actual containers and start the application inside them as per the instructions present in the image<strong><em>(We will see this below with a real example)</em></strong>.</p>
<p>There are a plethora of docker images which are commonly used for enterprise and personal use. Docker also maintains a registry from which we can download these images for various applications and use them. This registry is known as <a target="_blank" href="https://hub.docker.com/search?q=">DockerHub</a>.</p>
<p>So instead of installing some software like Redis, or Postgres on your local machine, you can simply run their images inside a container. At the same time, you can also expose and publish their ports inside the container to some port of your host machine to be able to access and use it on localhost.</p>
<p>You can also create your custom Docker image which could be built on top of these existing images and some additional commands as per the requirements. A <strong>Dockerfile</strong> is a document that contains all such commands a user requires to assemble an image. We will be using Dockerfile to create a custom docker image and run it in the example below.</p>
<blockquote>
<p>👉 Docker images also consist of logical sub-images called <strong>"layers"</strong>. Each layer stores some sub-part of the image it’s based on.</p>
<p>These layers are used to avoid transferring repetitive instructions which are already present and skip unnecessary build steps. For example, your image could have 5 layers, one of them being to download an "X" image from Dockerhub. Now, if you are building the same image again it should ideally not download the "X" image again from Dockerhub, instead, it will pull this existing layer itself as there is no change in that context.</p>
</blockquote>
<h3 id="heading-now-that-the-basics-are-covered-lets-learn-about-the-commonly-used-docker-commands-with-the-very-basic-use-case">Now that the basics are covered, <strong>let's learn about the commonly used docker commands with the very basic use case 🚀</strong></h3>
<p>Let's create a very simple Go application that prints <code>Hello World!</code>.</p>
<p>Let's build our custom docker image for this application and then start a docker container which runs that image of a simple Go application.</p>
<p>Create a new folder with two files- <code>main.go</code> and <code>Dockerfile</code></p>
<pre><code class="lang-go"><span class="hljs-comment">// main.go</span>
<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> { 
    fmt.Println(<span class="hljs-string">"Hello World!"</span>)
}
</code></pre>
<pre><code class="lang-yaml"><span class="hljs-comment">#### Dockerfile</span>
<span class="hljs-comment"># Download the golang 1.15 linux package from Dockerhub - https://hub.docker.com/layers/library/golang/1.15/images/sha256-eb7ebf06372b4930e0b9539b3510422c4860ec3361bb2f22b63a857990cf9efe</span>
<span class="hljs-string">FROM</span> <span class="hljs-string">golang:1.15</span>

<span class="hljs-comment"># create a build dir</span>
<span class="hljs-string">RUN</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">/build</span>
<span class="hljs-comment"># navigate to this build dir</span>
<span class="hljs-string">WORKDIR</span> <span class="hljs-string">/build</span>

<span class="hljs-comment"># copy the project itself</span>
<span class="hljs-string">COPY</span> <span class="hljs-string">.</span> <span class="hljs-string">.</span>
</code></pre>
<p>Now we need to create a docker image out of this Dockerfile</p>
<p>To do this, navigate to your projects folder from your CLI, run <code>docker build -t main-app .</code> command.</p>
<p>This command will create a docker image for your application. You can confirm whether the image is created or not by running <code>docker images</code> command.</p>
<p><em>Remember the image "layers" we discussed above? The image created using the above Dockerfile will have multiple layers, you can check this using</em> <code>docker inspect main-app</code> command.</p>
<p>The docker image created has the following instructions as per the above Dockerfile</p>
<ul>
<li><p>Fetch the go1.15 package from <a target="_blank" href="https://hub.docker.com/layers/library/golang/1.15/images/sha256-eb7ebf06372b4930e0b9539b3510422c4860ec3361bb2f22b63a857990cf9efe?context=explore">Dockerhub</a></p>
</li>
<li><p>Create a folder named <em>build</em> inside the container</p>
</li>
<li><p>Navigate to this <em>build</em> folder inside the container</p>
</li>
<li><p>Copy all the files from the local machine folder(which has <code>main.go</code> and <code>Dockerfile</code>) to that <em>build</em> folder inside the container</p>
</li>
</ul>
<p>Now, since the image is created, we need to run this image to execute the above commands. Images can be run using <code>docker run main-app</code></p>
<p>The above run command will create the container with the go1.15 Linux dependency and will copy the go program inside the build directory of the container.</p>
<p>To verify if the container is running or not, you can run <code>docker ps -a</code> in your CLI/terminal. This command will print container details like container id, image, status, ports, etc.</p>
<p><strong>Note:</strong> You will notice that the container had initially started running but also stopped in a fraction of second. This is because all the commands provided in Dockerfile were completely executed and no process was ongoing.</p>
<p>So for this example, instead of simply running the container(which will exit immediately), you can start the interactive command line shell inside the container environment while running it.</p>
<p>To do that, run the container using <code>docker run -it main-app /bin/bash</code> command. This will open up an interactive bash shell inside the container. Now if you run <code>docker ps -a</code> in the new CLI tab, you will see the container is not stopped yet as the /bin/bash shell process is still running inside that container.</p>
<p>You can execute your Linux commands inside that shell just like you would do in a system with Linux/Ubuntu OS. Here you can run <code>go run main.go</code> command which will print <code>Hello World!</code> as expected. Notice that this happened inside the container you had created.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674231856955/60e91fd8-c16e-436c-98a5-a2a2e226e3c6.png" alt class="image--center mx-auto" /></p>
<p>Alternatively, if you have already started the container for some other application and it's currently running, you can also run <code>docker exec -it &lt;container id&gt; /bin/bash</code> to enter into the container's CLI.</p>
<p>If you want to save the running container's settings and state, you can do that using <code>docker commit</code> command(check <a target="_blank" href="https://docs.docker.com/engine/reference/commandline/commit/">this</a> for more info on this command).</p>
<p>You can also copy a file from the docker environment back into your local environment using <code>docker cp &lt;container-id&gt;/&lt;path to your file&gt; &lt;path where you want to copy locally&gt;</code> , for example: <code>docker cp c7aec65deaf0:/build/main.go /Users/user1/Documents</code></p>
<p>You can stop the running container using <code>docker stop &lt;container-id&gt;</code> command.</p>
<p>Similarly, containers and images can be removed from your local system using</p>
<ul>
<li><p><code>docker rm &lt;container-ids&gt;</code></p>
</li>
<li><p><code>docker rmi &lt;image-name/&gt;</code></p>
</li>
</ul>
<h2 id="heading-recap">Recap 👀</h2>
<p><strong>Docker commands used:</strong></p>
<pre><code class="lang-bash">-&gt; docker build -t main-app .
-&gt; docker images
-&gt; docker inspect main-app
-&gt; docker run main-app
-&gt; docker ps -a
-&gt; docker run -it main-app /bin/bash
-&gt; docker <span class="hljs-built_in">exec</span> -it &lt;container id&gt; /bin/bash
-&gt; docker commit
-&gt; docker cp &lt;container-id&gt;/&lt;file path&gt; &lt;<span class="hljs-built_in">local</span> dir to store&gt;
-&gt; docker stop &lt;container-id&gt;
-&gt; docker rm &lt;container-ids&gt;
-&gt; docker rmi &lt;image-name/&gt;
</code></pre>
<hr />
<blockquote>
<p>Docker has an amazing official documentation as well ❤️</p>
<p>You can also check out Docker architecture at <a target="_blank" href="https://docs.docker.com/get-started/overview/#docker-architecture">https://docs.docker.com/get-started/overview/#docker-architecture</a>, or anything you want to know about docker at <a target="_blank" href="https://docs.docker.com/get-started/overview/#docker-architecture">https://docs.docker.com</a>.</p>
</blockquote>
<hr />
<p>If you found this article helpful, please comment and share this article 😃.</p>
<p>Let's connect 💫</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<p>You can also subscribe to my newsletter below to get an email notification on my latest posts. 💻</p>
]]></content:encoded></item><item><title><![CDATA[Build cross-platform executables in Go]]></title><description><![CDATA[If you have been working on the Go language, then you might probably know about the go build <filename> command which builds an executable file for the given filename's main function. This executable can then be run via the command line or just like ...]]></description><link>https://neelvikmani.hashnode.dev/build-cross-platform-executables-in-go</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/build-cross-platform-executables-in-go</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Mon, 16 Jan 2023 05:14:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672674187172/2fbc05dc-bb79-415c-a6d2-f02929f4ba38.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have been working on the Go language, then you might probably know about the <code>go build &lt;filename&gt;</code> command which builds an executable file for the given filename's main function. This executable can then be run via the command line or just like any usual exe files.</p>
<p>But this build command generates an executable file which is only supported for the current <strong>machine's platform</strong> and <strong>architecture</strong> on which it runs. So if you run the command from a 64-bit Mac, it will generate a <strong>macOS-based executable</strong>, which can be only run on x86_64 MacOS machines.</p>
<h2 id="heading-lets-try-this-out"><strong>Let's try this out</strong></h2>
<p>Create a go file <code>helloworld.go</code> with a very basic program -</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   fmt.Println(<span class="hljs-string">"Hello World!!"</span>)
}
</code></pre>
<p>Go to the terminal and run</p>
<pre><code class="lang-bash">go build helloworld.go
</code></pre>
<p>This will generate the executable binary named <code>helloworld</code> in the same directory. To check the type of this file, run <code>file helloworld</code> , it will print below</p>
<pre><code class="lang-bash">➜ file helloword
helloword: Mach-O 64-bit executable x86_64
</code></pre>
<p>Since I build it from my Mac, it says it's a 64-bit Mac-O executable.</p>
<h2 id="heading-where-does-the-problem-arise">Where does the problem arise</h2>
<p>We usually want to run these executables from our integration or production environments, where instances are Linux / ubuntu based, most of the time. If we have a go executable file, we don't need to have the Go installed on the system to run it, just like any executable.</p>
<p>If I copy this executable file from my local machine to the integration/production VMs and try to run the executable, it will throw an executable format error, as the executable file type was MacOS based but I tried to run it on Linux machines.</p>
<h2 id="heading-solution">Solution</h2>
<p>One approach to solve this is to copy the go program in the VM, install go and then run <code>go build</code> command from within that VM. But this is not usually recommended as it adds the additional overhead of installing Go and other supported packages inside the VMs whenever we spin up a new VM instance.</p>
<p>Another approach is to find out a way if we can build a Linux executable from our Mac itself so that we just copy that executable to our VM and run it.</p>
<p>Fortunately, we can. <strong>Go support cross-compilation!</strong> 🤟</p>
<p>Just run the below command and we have a go executable for the Linux platform</p>
<pre><code class="lang-bash">env GOOS=linux GOARCH=amd64 go build helloworld.go
</code></pre>
<ul>
<li><p>GOOS - Operating system for which we want to build this file</p>
</li>
<li><p>GOARCH - The architecture of the OS for which we want to build this file</p>
</li>
</ul>
<p>Once this command is succeeded, check the file type again using <code>file</code> command. It will show something like below</p>
<pre><code class="lang-bash">➜ file helloword
helloword: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked
</code></pre>
<ul>
<li><p>ELF**(Executable and Linkable Format),** is a common standard file format for executable files.</p>
</li>
<li><p>LSB executable stands for <strong>Linux Standard Base</strong> executable.</p>
</li>
</ul>
<p>With this, we just built a Linux executable file from our MacOS.</p>
<p>We can then copy this executable to your remote VM if required using the below <code>scp</code> command</p>
<pre><code class="lang-bash">➜ scp helloworld &lt;IPAdressOfYourVM&gt;:
</code></pre>
<p>Now, we can just ssh into the VM and run the executable</p>
<pre><code class="lang-bash">./helloworld
</code></pre>
<h3 id="heading-issues-with-packages-which-does-not-support-cross-compilation"><strong>Issues with packages which does not support cross-compilation</strong></h3>
<p>There are some packages which do not support cross-compilation, and if you are trying to build your script(<em>which uses those packages</em>) for a different platform, the build will fail and it will throw an error. One such package is <a target="_blank" href="https://github.com/confluentinc/confluent-kafka-go">confluent-kafka-go</a>(still <a target="_blank" href="https://github.com/confluentinc/confluent-kafka-go/issues/119">an open issue</a> 🙈) which does not support cross-compilation.</p>
<p>So in such cases, we can use docker to build it inside the Linux container itself instead of cross-compiling from MacOS.</p>
<ol>
<li>Create a new Dockerfile with the below content in the same directory which has the go script and go.mod file</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-string">FROM</span> <span class="hljs-string">golang:1.15</span>

<span class="hljs-comment"># create a build dir</span>
<span class="hljs-string">RUN</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">/build</span>
<span class="hljs-string">WORKDIR</span> <span class="hljs-string">/build</span>

<span class="hljs-string">ENV</span> <span class="hljs-string">CGO_ENABLED=0</span>

<span class="hljs-comment"># copy module dependencies</span>
<span class="hljs-string">COPY</span> <span class="hljs-string">go.mod</span> <span class="hljs-string">.</span>
<span class="hljs-string">COPY</span> <span class="hljs-string">go.sum</span> <span class="hljs-string">.</span>

<span class="hljs-comment"># copy the project itself</span>
<span class="hljs-string">COPY</span> <span class="hljs-string">.</span> <span class="hljs-string">.</span>
</code></pre>
<p>If you also want to install some packages in this image (example: git), then add that to the above Dockerfile at line 2. Example:</p>
<pre><code class="lang-yaml"><span class="hljs-string">FROM</span> <span class="hljs-string">golang:1.15</span>

<span class="hljs-comment"># Install git...</span>
<span class="hljs-string">RUN</span> <span class="hljs-string">apt-get</span> <span class="hljs-string">install</span> <span class="hljs-string">git</span>

<span class="hljs-comment"># create a build dir</span>
<span class="hljs-string">RUN</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">/build</span>
<span class="hljs-string">..</span>
<span class="hljs-string">..</span>
<span class="hljs-string">..</span>
</code></pre>
<ol>
<li>Generate a docker image from the above Dockerfile using the below command</li>
</ol>
<pre><code class="lang-bash">docker build -t go-cli-script .
</code></pre>
<ol>
<li>Run the above-created image inside a container and open a bash shell in this container with which we can interact, using the below command</li>
</ol>
<pre><code class="lang-bash">docker run -it go-cli-script /bin/bash
</code></pre>
<p>This command will open up the bash CLI from within the Linux container. Execute the below command in this CLI to generate the Linux executable.</p>
<pre><code class="lang-bash">go build helloworld.go
</code></pre>
<p>After performing the above step, a new linux executable would be added in the same directory inside the container.</p>
<p>Now, we want to copy this executable file from the container to the host machine,</p>
<p>To do this, run the below docker command in your local machine terminal-</p>
<pre><code class="lang-bash">docker cp &lt;container id&gt;:/build/helloworld &lt;<span class="hljs-built_in">local</span> machine directory <span class="hljs-built_in">where</span> you want to copy&gt;
</code></pre>
<p>The container id in the above command should be of the container we created using <code>docker run</code> command above. You can also get the container id by running <code>docker ps -a</code> command.</p>
<p>Check the copied file’s type in the local machine using <code>file helloworld</code> command, it will show LSB(Linux Standard Base) executable as expected.</p>
<hr />
<p>If you found this article helpful, please comment and share this article so that it reaches others. 😃 You can subscribe to my newsletter to get an email notification on my latest posts. 💻</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How internet works]]></title><description><![CDATA[In this article, we will answer the fundamental question of computer networking with some real-world examples. If you are someone who wants to understand the basic concepts of computer networking and how the internet works, then this article will hel...]]></description><link>https://neelvikmani.hashnode.dev/how-internet-works</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/how-internet-works</guid><category><![CDATA[Software Engineering]]></category><category><![CDATA[networking]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Wed, 11 Jan 2023 07:03:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/19af1721fbbfb0b2e17df812c0cb0e7c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will answer the fundamental question of computer networking with some real-world examples. If you are someone who wants to understand the basic concepts of computer networking and how the internet works, then this article will help you.</p>
<p>I will be answering a very basic question -</p>
<p><strong><em>If you open your browser and go to</em></strong> <strong><em>www.google.com</em></strong> <strong><em>or any other website, what happens in the background?</em></strong></p>
<p><strong>In a very basic sense</strong></p>
<ol>
<li><p>Browser (client) sends a <strong>request</strong> for this website over the internet.</p>
</li>
<li><p>The server (the service or machine which hosts this website) over the internet responds with the data.</p>
</li>
</ol>
<p>This is called the <strong>request-response</strong> paradigm and this is how computers communicate with each other over a network. The above communication follows <strong>the client-server</strong> model where the browser (client) requests some resources and the server responds. The communication happens in form of chunks of data, also known as <strong>data packets</strong> <em>(more on this below).</em></p>
<p>This data is transferred between the client and server using a series of steps and methods which follow certain <strong>protocols</strong> (rules).</p>
<p><strong>Let’s go down one level deeper and try to understand the core concepts and technologies involved here.</strong></p>
<h2 id="heading-ip-address">👉 IP Address</h2>
<p>The Internet is made up of billions of computers interconnected to each other via some network. Every resource has some identifier by which it can be <strong>uniquely</strong> identified over the internet. By resource, we mean anything which can be accessed over the internet, like websites, web applications, etc. This unique identifier is called an IP Address. IP addresses are numeric addresses in xx.xx.xx.xx format, for example, 127.0.0.1.</p>
<h2 id="heading-dns">👉 DNS</h2>
<p>In simple terms, DNS (Domain Name System) is the system of assigning some human-readable names to the not-so-human-readable IP addresses of the resources to access these resources(websites, etc) over the internet.</p>
<p>Since all internet resources are uniquely identified by IP Address, it is very difficult for a human to remember such IP addresses for the things they need. For example:</p>
<ul>
<li><p><a target="_blank" href="http://google.com">google.com</a> IP Address: <strong>142.250.199.174</strong></p>
</li>
<li><p><a target="_blank" href="http://facebook.com">facebook.com</a> IP Address: <strong>31.13.79.35</strong></p>
</li>
</ul>
<p>Too many numbers to remember!!!</p>
<p>That’s why we assign domain names to our web services and the DNS takes care of mapping it to the actual IP address of the host.</p>
<p>For example: When I type google.com in the browser, the DNS will internally check for the <a target="_blank" href="http://google.com">google.com</a> IP Address and then forward the request to that IP Address over the internet.</p>
<h2 id="heading-data-packets">👉 Data packets</h2>
<p>The communication between the client and server happens in the form of data packets. These packets contain the actual data to be sent along with the sender and receiver details like source and destination IP Addresses and Port numbers.</p>
<p>IP addresses are used to know which host or computer has requested the resource (for example your router) and the request is being sent to which destination host (google’s server host), whereas ports are used to identify the application or the software service within that host/device which requested the resource (browser).</p>
<h2 id="heading-a-typical-home-setup-for-accessing-the-internet">👉 A typical home setup for accessing the internet</h2>
<p>In a typical home setup, we have one router and all our devices like mobile, laptops, etc. are connected to this router for accessing the internet. We will use this real-world example to explain how it all works.</p>
<h2 id="heading-isp">👉 ISP</h2>
<p>We all are exposed to the internet via some <strong>ISP (Internet Service Provider)</strong>, for example, Vodafone, Airtel, or some local ISPs. These ISPs provide us with services by which we can access the internet.</p>
<p>If I connect my laptop to my home router and go to <a target="_blank" href="http://google.com">google.com</a> from my laptop’s browser, the request does not directly reach Google’s server. The request first goes from the laptop to the home router. Then it goes from the home router to the ISP and then over the internet.</p>
<blockquote>
<p>Local devices(phone/laptop, etc) -&gt; Router -&gt; ISP/s -&gt; Internet</p>
</blockquote>
<p>The ISPs also provide public IP Addresses to our local network routers, by which we are publicly identified over the internet. For the outside world/internet, all devices connected to this router will seem to have the same IP address, which is the same as the router.</p>
<p><strong><em>But wait, if the ISP is assigning only one IP Address to my Home Router, then how multiple devices connected to my router are being uniquely identified by my router?</em></strong></p>
<p>The answer to this question is <strong>DHCP.</strong></p>
<h2 id="heading-dhcp">👉 DHCP</h2>
<p>Whenever any devices are connected to the router for accessing the internet, the router assigns new unique IP addresses to the devices connected to it. These IP address assignments are done using <strong>DHCP (Dynamic Host Configuration Protocol)</strong>. These IP addresses are called <strong>private IP addresses</strong>, as the outside internet does not know about these IP Addresses. Internet only knows the IP address of the ISP, ISP in turn knows the IP Address of the router. So basically to trace back the request, the public internet will know about the ISP from which the request came, and the ISP will know from which specific router was the request made.</p>
<p><strong><em>Now, when the response comes back from</em></strong> <a target="_blank" href="http://google.com"><strong><em>google.com</em></strong></a><strong><em>, since the destination IP address was of the router, how does my home router know whether the response should be sent back to my laptop or mobile or computer?</em></strong></p>
<p><strong><em>And once it finds out the device( let’s say laptop), how does it know which service within that device should it be sending the response (for example browser, terminal, some gaming application, etc)?</em></strong></p>
<p>The answer is <strong>NAT</strong> and <strong>Port numbers</strong></p>
<h2 id="heading-nat-and-ports">👉 <strong>NAT and Ports</strong></h2>
<p><strong>NAT (Network Address Translation)</strong> is the process of translating the public IP address of the router to the private IP address <em>(which was assigned by the router to its connected devices using DHCP)</em> and vice versa whenever the packet goes from public to private network or from private or public network.</p>
<p><strong>Port numbers</strong> are used to identify the service or the application within the host (for example browser in your laptop) which made the request.</p>
<p>When you hit <a target="_blank" href="http://google.com">google.com</a> from your laptop’s browser, the outgoing packet has the source IP address value as your laptop's private IP address (<em>the one which was assigned by the router using DHCP</em>) and the port number as the service(browser) identifier.</p>
<p>This request packet reaches your home router, here <strong>NAT</strong> updates the source IP address as the IP address of the router. It also <strong>masks*</strong> the source port number and then finally adds the corresponding entry in the <strong>NAT Table.</strong> When the response is received back to the home router from the internet, the NAT again checks this table to determine the exact host/device and the port/service to which the reply should be sent.</p>
<p>*<em>NAT does the masking of the port number to avoid the problem which can arise if two different hosts/devices connected to the same router request a resource over the same port. As the NAT table will have a public IP address, a private IP Address and a port number entry, once the response comes back from the internet to the router, it will be unsure which host should the reply be sent to.</em></p>
<p>The clients who are requesting some resource over the internet can also specify some <strong>ephemeral port numbers</strong> instead of the default port of service which initiated the request. These ports are short-lived port numbers that clients can specify and expect a response on these ports.</p>
<p>This is useful if you have multiple processes running for the same service. The browser tab is the best example of this. Each new tab you open in your web browser will assign a new ephemeral port for that particular channel and this is how the router will know which specific browser tab had initiated the <a target="_blank" href="http://google.com">google.com</a> request.</p>
<h2 id="heading-communication-from-isp-and-above">👉 Communication from ISP and above</h2>
<p>The Internet is nothing but a large number of computers or hosts connected. So once the ISP forwards the request over the internet, the request might hop through a series of hosts before it finally reaches the server which is responsible for serving the request (in our case it is the server of google.com).</p>
<p>Routers have <strong>routing tables</strong> and <strong>forwarding tables</strong> which help in the data packet routing. The routing table is the data table which stores all the possible paths required to reach the destination host or router, and the forwarding table helps in actually forwarding the data packet to the next hop.</p>
<p>For example: If I made a request to <a target="_blank" href="http://google.com">google.com</a> from Mumbai, India, the request might be served by some server in the USA. The request might travel from India to UAE, UAE to Austria, and Austria to the USA till it reaches the destination host which can serve the request.</p>
<p>Once the request reaches the server, the server will respond to the request and sends back the required data using the same technique as discussed above. The response will reach the source router (which made the request) via the same public internet and then NAT and ports will take up from there to send the response to the right host and service.</p>
<p>Usually, ISPs are classified into three tiers.</p>
<p>Tier 3 or Tier 2 ISPs are the local or national ISPs which serve some specific local areas or metropolitan regions within a country. Examples of some Tier 2 ISPs are Vodafone, Airtel, etc.</p>
<p>Tier 1 ISPs are the international ISPs which are responsible for connecting other lower-tier ISPs to the global internet. An example of a Tier 1 ISP is <em>Tata Communications, etc.</em></p>
<p>These ISPs are also the ones who own the <strong>submarine cables</strong> under the oceans via which the actual internet data is transferred between nations and continents and how the whole internet works globally.</p>
<p><strong><em>The whole world is connected not wirelessly, but via the actual submarine cables under the seas and oceans. Check this out —</em></strong> <a target="_blank" href="https://www.submarinecablemap.com"><strong><em>https://www.submarinecablemap.com</em></strong></a><strong><em>. Isn’t it interesting?</em></strong> 🤩</p>
<h2 id="heading-other-commonly-used-protocols-over-the-web">👉 Other commonly used protocols over the web</h2>
<p>There are a lot of protocols which are used in computer networking, but we will be covering the protocols which are most commonly used over the web. They are TCP, UDP and HTTP/s. Below is a basic and short explanation of these protocols. This explanation should be sufficient for starters, although you can read about them in detail later over the internet.</p>
<h3 id="heading-https"><strong>HTTP/s</strong></h3>
<p>This is used by web browsers. This protocol defines the format of the data being transferred through the web. It mentions how the communication should take place between client and server, like how the client will request the data, what will be the format of the data, and how the server should respond to the client. This is a <strong>connectionless</strong> and <strong>stateless</strong> protocol. Connectionless means that the connection is maintained only till the client receives the response from the server, and not forever. Stateless means that the state (data) involved in a particular request and response is only available during that request and response time only.</p>
<h3 id="heading-tcp">TCP</h3>
<p>This is a <strong>connection-oriented</strong> protocol which means that the connection needs to be established between both parties (for example client and server) before actually transmitting the data. It is a <strong>reliable</strong> protocol which ensures data delivery and <strong>no data loss once th</strong>e connection is created. To establish connection, TCP uses a 3-way handshake(using SYN, SYN-ACK, and ACK signals) to establish a reliable connection.</p>
<h3 id="heading-udp">UDP</h3>
<p>It is a <strong>connection-less</strong> protocol which means that the connection is not needed for the client and server to communicate. This also means that the data sent across between the client and server is not guaranteed for delivery as the acknowledgement flags are not present here. The upside of this protocol is that it is faster (low latency) than TCP. This protocol is used across applications where we need low latency and it is fine if the data packets are dropped. The most common applications are real-time services like gaming, video calls, etc.</p>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>Apart from these technologies, there are various other technologies as well which are widely used across the internet, like CDN, etc. which we will cover in some other article.</p>
<p>If you found this article helpful, please like, comment and share this article so that it reaches others. 😃</p>
<p>For more such content, please subscribe to my newsletter so that you get an email notification on my latest post. 💻</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/">LinkedIn</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr">GitHub</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Web Services in detail]]></title><description><![CDATA[A lot of you may have heard about web services but don’t know what they are and how they work. Well, just like any other concept, they are easy to understand if you interpret them right.
In this article, I will try to explain it in the best possible ...]]></description><link>https://neelvikmani.hashnode.dev/web-services-in-detail</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/web-services-in-detail</guid><category><![CDATA[webservice]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Fri, 30 Dec 2022 04:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672223649775/b8a1a4f3-e9ad-4ac4-9d38-9586df76549e.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A lot of you may have heard about web services but don’t know what they are and how they work. Well, just like any other concept, they are easy to understand if you interpret them right.</p>
<p>In this article, I will try to explain it in the best possible way right from the basics, differentiating it from many other similar concepts and why are they used extensively today.</p>
<h2 id="heading-firstly-lets-understand-the-difference-between-a-website-and-a-web-application">Firstly, let's understand the difference between a website and a web application</h2>
<p>A website is a collection of static web pages. Static here means that the data or information is hard-coded and do not require any inputs from a user or communications with the database. An example of a static website can be any small business website which has only services and contact us pages with content embedded in HTML itself.</p>
<p>Web applications, on the other hand, are dynamic websites which constantly require communicating with databases or back-end services for data or information to be presented to the end user. Examples of web applications are hashnode.com, amazon.com, etc.</p>
<h3 id="heading-a-thought">A thought 💡</h3>
<p>Do you think that massive applications such as Gmail, and Uber use a single programming language for all their development?</p>
<p>There are thousands of services running each second on their data centres to cope with users' demands and requests. These services may be executing various programs written in various programming languages and even running on different platforms.</p>
<p>Since there are more than one language and technologies used in developing one big web application, you might wonder how these different programs that are written in different languages communicate with each other.</p>
<p>If each language has its syntax and way of interpreting things, how do they understand what programs written in different applications wish to communicate?</p>
<p>Is there any standard way that all different programs can use to communicate with each other? (Just like each country have its native language, they can use English to communicate with anyone outside their country)</p>
<p><strong>The answer is Yes. There is, and this is what we call a Web Service.</strong></p>
<h2 id="heading-web-service"><strong>Web Service</strong></h2>
<p>Web service enables communication among different applications over the web using some standard protocol/method. Using web services, two different applications can talk to each other and exchange information.</p>
<p>Typically, a web service provider, who wants to provide its functionality to be used by other applications, develops a service and makes it available over the Internet. Any application can request the service from the server where it is hosted and the server responds to that request.</p>
<p>Two notable concepts come into the picture here — <strong>WSDL</strong> and <strong>UDDI</strong>. Putting in simple terms, WSDL(Web Services Description Language) provides information about the functionalities of any particular web service, and UDDI(Universal Description, Discovery, and Integration) is kind of a distributed directory of web services, where the server can publish their services, and clients can lookup to find any service. So, UDDI documents can have entries of multiple web services, and each web service may have its WSDL document.</p>
<p>The question arises again that how these applications communicate. The two important factors to think of are</p>
<ul>
<li><p><strong>The medium</strong> through which the data or information flows from one application to another</p>
</li>
<li><p><strong>The format</strong> in which the information is transferred.</p>
</li>
</ul>
<p>For example, while speaking over the telephone, the medium is the <strong>phone and the format is English</strong> or any language that both of you know.</p>
<p>Currently, two <strong>formats</strong> for communication between applications are universally accepted — XML and JSON.</p>
<p>Below is an example of the representation of students' data using JSON and XML.</p>
<p>Let's say there are 2 student records, each record has the student's name, email and city.</p>
<p><strong>XML representation</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">students</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>John<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">email</span>&gt;</span>john@xyz.com<span class="hljs-tag">&lt;/<span class="hljs-name">email</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">city</span>&gt;</span>Boston<span class="hljs-tag">&lt;/<span class="hljs-name">city</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>Julie<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">email</span>&gt;</span>julie@xyz.com<span class="hljs-tag">&lt;/<span class="hljs-name">email</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">city</span>&gt;</span>London<span class="hljs-tag">&lt;/<span class="hljs-name">city</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">students</span>&gt;</span>
</code></pre>
<p><strong>JSON representation</strong></p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"students"</span>: [
        {<span class="hljs-attr">"name"</span>:<span class="hljs-string">"John"</span>, <span class="hljs-attr">"email"</span>:<span class="hljs-string">"john@xyz.com"</span>, <span class="hljs-attr">"city"</span>:<span class="hljs-string">"Boston"</span>},
        {<span class="hljs-attr">"name"</span>:<span class="hljs-string">"Julie"</span>, <span class="hljs-attr">"email"</span>:<span class="hljs-string">"julie@xyz.com"</span>, <span class="hljs-attr">"city"</span>:<span class="hljs-string">"London"</span>}
    ]
}
</code></pre>
<p>You can see that JSON is easier to write and understand.</p>
<p>JSON is used on a larger scale than XML because it is lightweight and easy to understand.</p>
<p>Now, coming to the <strong>medium</strong> through which the data is transferred. Web services use <strong>HTTP</strong>(Hypertext Transfer Protocol) for sending requests and responses over the web.</p>
<p>HTTP uses a request/response technique, that is, communication or transfer of information between web server and browser is done through HTTP request and response packets.</p>
<p>For example, the web server is where all files related to the website are present; the browser or client sends a request for an HTML page, and the server responds with the requested page. Similarly, the browser may request some information from the server by sending an HTTP request, and the server processes the request and provides appropriate responses as an HTTP response in the <strong>format(XML or JSON)</strong> discussed above.</p>
<p>Now that you know the fundamental concepts of web service, let’s dig into the types of web services</p>
<h3 id="heading-types-of-web-service">Types of Web Service</h3>
<p>Primarily, there are two types of web services-</p>
<ul>
<li><p>SOAP web services</p>
</li>
<li><p>RESTful web services</p>
</li>
</ul>
<p>In SOAP(Simple Object Access Protocol) based web service, all the information exchange happens over a single common format — <strong>XML</strong>. These XML-based messages have a defined structure, which is known as SOAP Message. Each of these SOAP messages consists of an Envelope, which has a header and body.</p>
<blockquote>
<p>Remember that web services are used to communicate between two different applications, platforms, or browsers and servers, so these services need to have all information required for the efficient transmission of any message.</p>
</blockquote>
<p>In SOAP envelope, the header provides information about the message itself and also includes routing information, and authentication information, if any. The body contains the actual data that needs to be sent.</p>
<p><strong>RESTful</strong> web services communicate between applications using REST principles. <strong>REST(Representational State Transfer)</strong> is an architectural style which defines how communication happens between two different applications. And how it happens is <strong>uniform</strong> and <strong>stateless</strong>.</p>
<blockquote>
<p>Two major principles of REST are <strong>uniform interface</strong> and <strong>statelessness</strong>.</p>
</blockquote>
<p><strong>A uniform interface</strong> means everything in RESTful web service is a resource. The resource can be data, information or any block of data. This means that there is no distinguished part which cannot be accessed or accessed differently, everything is accessed by a <strong>URI(Uniform Resource identifier).</strong></p>
<p>Also, RESTful web services make use of HTTP methods for the exchange of information. Oh sorry, I meant the exchange of <strong>resources</strong>. 😄</p>
<p>For example, HTTP methods like GET, PUT, POST and DELETE can be used to request some resource specified in URI itself.</p>
<p>Suppose I want to get details of all student records from XYZ website, I can use GET</p>
<p><code>GET</code> <a target="_blank" href="http://www.xyz.com/students"><code>www.xyz.com/students</code></a></p>
<p>or if I need detail of a particular student with ID 12345</p>
<p><code>GET</code> <a target="_blank" href="http://www.xyz.com/student/12345"><code>www.xyz.com/student/12345</code></a></p>
<p>Similarly -</p>
<ul>
<li><p>PUT can be used to update the existing resource details</p>
</li>
<li><p>POST can be used to add new resources</p>
</li>
<li><p>DELETE can be used to delete a resource.</p>
</li>
</ul>
<p>In the above example, I can use the PUT method and specify the updated value of any detail, like the name or email of the student in my body.</p>
<p>Similarly, I can use the POST method to add a new student record and the DELETE method to delete a student record.</p>
<blockquote>
<p>If you are building a web service or an API in a RESTful manner, you must specify the appropriate functionality and response that you want to give for any given HTTP requests received through URI.</p>
</blockquote>
<p><strong>Stateless</strong> <strong>communication</strong> means there is no previous information or data that is required to send a current request or response. Every request or response contains all the information itself and does not rely on any previous state of messages.</p>
<p>REST also supports caching and layered approaches. Various layers of components can be added between the client and server like a proxy server, gateways, etc.</p>
<p>Also, REST supports XML and JSON format, whereas SOAP only supports XML.</p>
<p>Because of all these principles and differences, REST is preferred over SOAP.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Web services are widely used today for communication and exchanging data between disparate applications or platforms. Technology is growing at a faster rate and more connectivity and seamless integration of services ensure greater experience and value for users. RESTful web services are dominant for most reasons, and REST is widely used in developing APIs and web services today.</p>
<hr />
<p>If you found this article helpful, please like, comment and share this article so that it reaches others. 😃</p>
<p>For more such content, please subscribe to my newsletter so that you get an email notification on my latest post. 💻</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[5 useful concepts of Ruby on Rails]]></title><description><![CDATA[You may ask "Why would anyone want to work on something so old as Ruby on Rails even if there are newer alternatives available?" - I used to ask myself this same question when I started working on Ruby on Rails.
But then eventually as I started contr...]]></description><link>https://neelvikmani.hashnode.dev/ruby-on-rails-concepts-explained-with-real-world-use-cases</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/ruby-on-rails-concepts-explained-with-real-world-use-cases</guid><category><![CDATA[Ruby on Rails]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Wed, 28 Dec 2022 06:53:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672841014907/f6c5e6d4-0616-4165-901a-36c061926831.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>You may ask</em> <strong><em>"Why would anyone want to work on something so old as Ruby on Rails even if there are newer alternatives available?"</em></strong> <em>-</em> I used to ask myself this same question when I started working on Ruby on Rails.</p>
<p>But then eventually as I started contributing to the project, I started loving this awesome framework.</p>
<p>I have worked on the RoR framework for over 2 years, and here I am sharing the experience and knowledge I have gained working on production applications using RoR.</p>
<h2 id="heading-why-ruby-on-rails">Why Ruby on Rails 💡</h2>
<p>The biggest competitive advantage of using Ruby on Rails over other frameworks is the vast ecosystem, framework maturity and speed of product development.</p>
<p>On top of this, it has lots of supporting libraries, which will help you even more in your development journey.</p>
<p>It is known for its easy syntax and rapid programming so that you can focus on more important aspects like system designs, integrations and other engineering principles like testability and maintainability.</p>
<p>With all the pros above, it also comes with its challenges like slow runtime or slow performance at very high throughputs, hence it is mostly preferred by startups who are still scaling up and trying out different things and shipping features fast.</p>
<h2 id="heading-lets-start-with-the-concepts">Let's start with the concepts 💫</h2>
<p>First things first, I will start with a very common use case, upon which all further concepts will be explained. Let's consider the backend of a <strong>"product catalogue</strong> <strong>service"</strong> in an e-commerce company. This backend service deals with</p>
<ul>
<li><p>Product creation and updation</p>
</li>
<li><p>Exposing product details to the outside world or other services within organizations via APIs</p>
</li>
<li><p>Broadcasting the product updates asynchronously via some message-passing mechanisms.</p>
</li>
</ul>
<p>Let’s create a new rails project using the command:</p>
<pre><code class="lang-ruby">rails new catalog
</code></pre>
<blockquote>
<p>Note: For demonstration purposes, I will be using <strong>MySQL</strong> database and <strong>ActiveRecord</strong> ORM for interacting with the database.</p>
<p>Don't know what is ORM ? - Object-relational mapping (ORM) is <strong>a mechanism that makes it easier to access and manipulate database objects without actually writing raw SQL queries.</strong></p>
</blockquote>
<h3 id="heading-1-mvc-model-view-controller"><strong>1. MVC (Model-View-Controller)</strong></h3>
<p>This is the most common design pattern that many frameworks support, including Laravel, Spring MVC, Ruby on Rails, etc.</p>
<p>Putting it most simply, MVC is a software design pattern that divides the application into three interconnected elements, namely Model, View, and Controller. The basic idea is that each application consists of these three elements-</p>
<ol>
<li><p><strong><em>The model</em></strong> holds the data</p>
</li>
<li><p><strong><em>The view</em></strong> makes the application look nice with clean layouts and consistent data display</p>
</li>
<li><p><strong><em>The controller</em></strong> controls the flow between the Model and View, i.e. how the data flows through and out of the application.</p>
</li>
</ol>
<p>MVC pattern allows having maintainable and segregated code, which can work wonderous in making further changes as the application scales from MVP to large-scale systems.</p>
<p><strong>Use case:</strong></p>
<p>Let’s take this use case where the user wants to get product information. When they click on a particular product, they are directed to the PDP(Product Details Page) of that product.</p>
<p>Now you may think it as simple as exposing a GET API with endpoint /products/{product_id} and when the request comes to this API, just hit the <code>product</code>table in the database and get the results and show it on the web page. Well, the approach is straightforward, but with the MVC pattern, you can make these requests handling more maintainable and clean.</p>
<p>With rails and MySQL installed in your system, just navigate to your project folder using the terminal and run the below command -</p>
<pre><code class="lang-ruby">rails generate model Product <span class="hljs-symbol">name:</span>string
</code></pre>
<p>This command will create a model file named <code>product.rb</code> in the <code>app/models</code> folder and will also create a migration file in <code>db/migrate</code> folder, which will look like the below-</p>
<p><strong>Model file (product.rb)</strong></p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Product</span> &lt; ApplicationRecord</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p><strong>Migration File (_create_products.rb)</strong></p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CreateProducts</span> &lt; ActiveRecord::Migration[5.2]</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">change</span></span>
        create_table <span class="hljs-symbol">:products</span> <span class="hljs-keyword">do</span> <span class="hljs-params">|t|</span>
            t.string <span class="hljs-symbol">:name</span>

            t.timestamps
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Now, you need to run this migration to be able to create the actual product table in the database. You can also add some more fields to this file if you need some additional attributes in the product table. After the required changes are done, run migrations using the command -</p>
<pre><code class="lang-bash">rake db:migrate
</code></pre>
<p>This will create the actual table in the database.</p>
<p>Now since you are all set with the tables and model in hand, let us create a controller.</p>
<p>Go to the terminal and run the below command</p>
<pre><code class="lang-bash">rails generate controller Product
</code></pre>
<p>This will create a <code>product_controller.rb</code> file inside <code>app/controllers</code> folder with the following content:</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProductController</span> &lt; ApplicationController</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>It will also create an empty <code>app/views/product</code> folder, which you can use for defining views for our application. You can also use this file along with any routing mechanisms for developing full-stack web applications.</p>
<p>So now instead of maintaining your code in a single file or making custom secondary files and handling processing between each of them, this MVC architecture lays down a common and sleek code structure and design pattern that you need to follow for making your application code more maintainable.</p>
<blockquote>
<p>One of the principles of Ruby on Rails is the ‘Fat Model, Skinny Controller’, which means making the controller as simple and atomic as possible and providing all transformation and processing logic in the model. I will be using this same principle most easily in the next few concepts.</p>
</blockquote>
<h3 id="heading-2-trailblazers"><strong>2. Trailblazers</strong></h3>
<p>This is a concept that has been used widely across many organizations for designing and implementing business logic layers into comprehensive and maintainable code.</p>
<p>As their website quotes-</p>
<blockquote>
<p>“Trailblazer’s file structure organizes by <strong>CONCEPT</strong>, and then by technology.”</p>
</blockquote>
<p>They seriously mean it!</p>
<p>The approach of writing, dividing and structuring implementation code into concepts and practising modularity at the code level is the best thing for which you will thank yourself once the production application grows big time.</p>
<p><strong>Use case:</strong></p>
<p>Let’s say you have a product availability logic which determines whether any product is available in the inventory at a specified city or not.</p>
<p>Let us assume that availability logic requires read access to 3 to 4 tables and also requires some Redis calls to fetch related data, and at the end requires processing at the application end before giving the actual availability.</p>
<p>Now you want to do all these things every time someone hits Catalog interface services or APIs. So, for any requested product in any city, the catalog must provide actual availability precisely.</p>
<p>Implementing all of this at the Model Level or Controller Level alone is a bad practice as the logic may talk to several models and also it may scale in the future. This is where the Trailblazer concept can come into the picture.</p>
<p>A sample trailblazer operation file for calculating availability will look like this-</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProductAvailability</span> &lt; Trailblazer::Operation</span>
    step <span class="hljs-symbol">:read_params</span>
    step <span class="hljs-symbol">:fetch_product_and_location_details</span>
    step <span class="hljs-symbol">:calculate_availability</span>
    step <span class="hljs-symbol">:persist_and_build_output</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_params</span><span class="hljs-params">(options)</span></span>
    <span class="hljs-comment"># logic to read the product and location id params passed</span>
    <span class="hljs-comment">#if params not passed, return false (this will exit the concept and return to the caller)</span>
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fetch_product_and_location_details</span><span class="hljs-params">(options)</span></span>
    <span class="hljs-comment"># hit db/cache to fetch location and product details</span>
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculate_availability</span><span class="hljs-params">(options)</span></span>
    <span class="hljs-comment"># logic to calculate availability for a product-location</span>
    <span class="hljs-keyword">end</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">persist_and_build_output</span><span class="hljs-params">(options)</span></span>
    <span class="hljs-comment"># store the availability calculated and return the response</span>
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>You must have observed a parameter named <code>options</code> in the above file. It is the parameter of the type <code>map</code>, which is common to the whole concept.</p>
<p>So you can assign some values to this hashmap in the first concept function and read that in the next one, and also return the values to the caller. <strong>Example</strong>: you can assign <strong>product details</strong> to <code>options[:product]</code> in the second function and access it in the third function, you can assign <strong>the final response</strong> to <code>options[:result]</code> and return, and refer to this <code>result</code> from the caller.</p>
<p>So options value can look like this:-</p>
<pre><code class="lang-json">options = {:product: {:id:<span class="hljs-number">123</span>, :name: <span class="hljs-string">"P1"</span>}, :result: {:availability: <span class="hljs-string">"IN_STOCK"</span>}}
</code></pre>
<p>Also, as specified in the first function, returning false from any of the "step" stops the current flow of concept and returns to the caller with the values added to this <code>options</code> variable till that time.</p>
<p>Apart from operations, there are other related functions that this awesome framework provides. You can explore them here- <a target="_blank" href="http://trailblazer.to/">http://trailblazer.to/</a>.</p>
<h3 id="heading-3-active-jobs">3. Active Jobs</h3>
<p>This is a framework where you can declare async jobs and run them on any queuing services. Jobs can be used for -</p>
<ul>
<li><p>Runnin cron / daily cleanup tasks</p>
</li>
<li><p>Sending events to a couple of services</p>
</li>
<li><p>Running some calculations or processing some update event of a record in the model.</p>
</li>
</ul>
<p>Active jobs run parallel and in a separate thread from the current main application thread.</p>
<p>Rails provide this Active Job framework where you can create a job, enqueue the jobs on certain events, specify a queue where the job should get enqueued, execute it, and many more functions.</p>
<p><strong>Use case:</strong></p>
<p>Let’s say that the catalog service gets the product details from another microservice through a Kafka queue, processes it and persists it in its database.</p>
<p>Some attributes of the product might also influence the availability of that product(like if a product is discontinued or banned), so you need to call the availability concept that we saw in the earlier example, to recalculate the availability for that product, and persist it back in the database.</p>
<p>This should be done parallelly so that the current application thread is not strained or blocked with additional overhead.</p>
<p>To do this, create a new file  <code>app/jobs/recalculate_availability_job.rb</code>, with job name as <code>RecalculateAvailabilityJob</code>. Accept <code>product_id</code> parameter to this job and in this job, call the availability concept which we saw in the earlier use case inside this function. Snippet added below-</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RecalculateAvailabilityJob</span> &lt; ApplicationJob</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">perform</span><span class="hljs-params">(p_id)</span></span>
        ProductAvailability.call <span class="hljs-symbol">product_id:</span> p_id
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Now, in your Product model, use an <code>after-commit</code> hook to trigger the above job whenever the product's discontinued attribute is changed.</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Product</span> &lt; ApplicationRecord</span>
    after_commit <span class="hljs-symbol">:recalculate_availability</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">recalculate_availability</span></span>
        <span class="hljs-keyword">if</span> discontinued_previously_changed?
            RecalculateAvailabilityJob.perform_later id
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Here, <code>perform_later</code> is the keyword that enqueues the job to be performed as soon as the queue gets empty.</p>
<p>So with the above code, whenever an attribute <code>discontinued</code> of any product is changed, this job gets enqueued which gets processed by a different thread and it calls the availability concept for the same product whose attribute was changed.</p>
<h3 id="heading-4-mailers">4. Mailers</h3>
<p>As the name suggests, this script is used to send emails.</p>
<p><strong>Use case:</strong></p>
<p>You want to notify certain people about a product whenever it is banned.</p>
<p>Just create <code>banned_product_mailer.rb</code> in <code>app/mailers/</code> folder as below-</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BannedProductMailer</span> &lt; ApplicationMailer</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_mail</span><span class="hljs-params">(<span class="hljs-symbol">name:</span>, <span class="hljs-symbol">email_id:</span>)</span></span>
        attachments[<span class="hljs-string">'banned_products.txt'</span>] = { <span class="hljs-symbol">mime_type:</span> <span class="hljs-string">'text/plain'</span>, <span class="hljs-symbol">content:</span> name.join(<span class="hljs-string">"\n"</span>) }
        mail(<span class="hljs-symbol">to:</span> email_id, <span class="hljs-symbol">subject:</span> <span class="hljs-string">"Banned Products Alert: <span class="hljs-subst">#{ENV[<span class="hljs-string">'RAILS_ENV'</span>]}</span>"</span>) <span class="hljs-keyword">do</span> <span class="hljs-params">|format|</span>
        body = <span class="hljs-string">"PFA <span class="hljs-subst">#{result.count}</span> banned/unbanned products"</span>
        format.text { render <span class="hljs-symbol">plain:</span> body }
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Now, in your Product model, use another after-commit to send an email when the banned attribute of the product model is made true.</p>
<pre><code class="lang-ruby"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Product</span> &lt; ApplicationRecord</span>
    after_commit <span class="hljs-symbol">:send_mail_on_banned</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_mail_on_banned</span></span>
        mail_ids = JSON.parse(ENV[<span class="hljs-string">'BANNED_PRODUCT_MAIL_IDS'</span>])
        <span class="hljs-keyword">if</span> banned_previously_changed? &amp;&amp; banned_previous_change[<span class="hljs-number">1</span>]
            BannedProductMailer.send_mail(<span class="hljs-symbol">name:</span> name, <span class="hljs-symbol">email_id:</span>)
        <span class="hljs-keyword">end</span>
    <span class="hljs-keyword">end</span>
<span class="hljs-keyword">end</span>
</code></pre>
<h3 id="heading-5-rake-tasks">5. Rake Tasks</h3>
<p>These are the <strong>one-time scripts</strong> that you can write once and deploy, and then execute via console whenever you need to run it. These tasks are written for a specific purpose like performing data cleanup, updating some data, performing indexing of all the records, etc.</p>
<p>Since the developer doesn’t have access to manually update the production data, these kinds of tasks are very useful if there are any cleanups, small data anomaly fixes or some ad-hoc tasks that need to be run</p>
<p><strong>For example,</strong> I developed a rake task to update any column value of a table. This had been used several times by our team for updating values for some ad-hoc requirements as well as for critical short-term data anomaly fixes.</p>
<p>Similarly, you can write rake tasks for your use case to provide solutions for some of the common problems.</p>
<p>To write a rake task, create a directory named <code>tasks</code> or <code>scripts</code> and inside this directory, create a file for a task which you need to run with <code>.rake</code> extension.</p>
<p>Sample task: <code>hello_world.rake</code></p>
<pre><code class="lang-ruby">desc <span class="hljs-string">"Print Hello world"</span>
task <span class="hljs-symbol">:print_hello_world</span> <span class="hljs-keyword">do</span>
    puts <span class="hljs-string">"Hello World!"</span>
<span class="hljs-keyword">end</span>
</code></pre>
<p>Run this task via the terminal using the below command</p>
<pre><code class="lang-ruby">rake print_hello_world
</code></pre>
<hr />
<h3 id="heading-bonus">🌟 Bonus 🌟</h3>
<p>Since you have read the article up to here, here is a small bonus.</p>
<p>Below are the most commonly used <strong>Ruby's in-built functions and objects</strong> that I have found most useful and have used extensively while working on the project.</p>
<p>1. map, split, join, flatten, etc - <a target="_blank" href="https://www.rubyguides.com/2018/10/ruby-map-method/"><strong>How to Use The Ruby Map Method (With Examples)</strong></a></p>
<p>2. procs and lambdas - <a target="_blank" href="https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/"><strong>Ruby Blocks, Procs &amp; Lambdas - The Ultimate Guide!</strong></a></p>
<p>3. <a target="_blank" href="https://apidock.com/ruby/Array/permutation"><strong>permutation</strong></a></p>
<p>4. <a target="_blank" href="https://apidock.com/ruby/Array/combination"><strong>combination</strong></a></p>
<p>Apart from these, there are many more functions, objects, and block patterns in Ruby, which you can explore and implement in your applications, but the above four are the ones which I have found most useful and used 80% of the time.</p>
<hr />
<p>If you found this article helpful, please like, comment and share this article so that it reaches others. 😃</p>
<p>For more such content, please subscribe to my newsletter so that you get an email notification on my latest post. 💻</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr"><strong>GitHub</strong></a></p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[Avoid common mistakes as a web developer]]></title><description><![CDATA[In this article, I will be talking about the mistakes that most people make in the process of developing web applications by handling both back-end and front-end at once and being a "full-stack" developer. Following the points mentioned in this artic...]]></description><link>https://neelvikmani.hashnode.dev/common-mistakes-in-web-development</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/common-mistakes-in-web-development</guid><category><![CDATA[Web Development]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Tue, 27 Dec 2022 18:14:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/e0373af1455817a6875fdcfecf9e6875.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I will be talking about the mistakes that most people make in the <strong>process</strong> of developing web applications by handling both back-end and front-end at once and being a "full-stack" developer. Following the points mentioned in this article will help you be productive in your web development journey.</p>
<p>Most people don’t plan how to manage both front-end and back-end programming simultaneously and ultimately end up wasting a lot of time doing unwanted repetitive tasks.</p>
<p>The intellect is not about being able to know both sides of the technology, but it is about the <strong>way you manage</strong> your development task. It is about having a balanced and systematic approach for coordinating the frontend and backend tasks and getting rid of redundant and stressful tasks.</p>
<h2 id="heading-design-first">Design First 💡</h2>
<blockquote>
<p>Give me six hours to chop down a tree and I will spend the first four sharpening the axe. -Abraham Lincoln</p>
</blockquote>
<p>No matter how simple or complex your application is, single or multiple pages, always design the UI and interactions, and the high-level design of your application. This applies only when you are also handling front-end tasks. If you don’t prepare a design before development, you will find yourself confused and stuck in the colours or pixels of each UI component continuously until you feel it is good, and the fact is you would not be satisfied with your UI for a very long time. This will drastically reduce your speed of programming and also stress your mind doing redundant activities.</p>
<p>Use tools such as <strong>Adobe XD, Figma</strong> or <strong>Sketch</strong> for designing the UI. Prototype your design to understand the interactions between various UI components.</p>
<h2 id="heading-ask-ask-ask">Ask ask ask!</h2>
<p>Developing an application for a client? Have a thorough session with them, discuss their interests, plans, any design pattern that must be followed, existing branding campaigns and brand resources they already have, like logo or colour palette.</p>
<p>Try to understand the end user’s needs, and design a persona for the users.</p>
<p><strong>Don't start front-end programming until the design is approved by your client!</strong></p>
<p>Schedule your development plan accordingly and stick to it and also have constant communication with your client at some planned milestones.</p>
<h2 id="heading-follow-the-incremental-approach">Follow the incremental approach</h2>
<p>Suppose you want to build a library management application on the web, then divide the main application into several sub-applications. Implement those sub-applications first, develop their UI, and backend implementation, and test it completely before moving it to the next sub-application.</p>
<p>Let's say login and signup is the first sub-application. First make a minimal front-end, without any CSS stylings, with all necessary HTML components like forms or input tags that are required for user inputs.</p>
<p>Now implement middleware or back-end functionalities and test the application for inputs and responses from databases.</p>
<p>Finally, style your UI components completely using simply CSS or some front-end framework.</p>
<p>Now repeat this task for each sub-application in a bottom-up manner(also take care of integrations of these sub-tasks) until you build a complete application.</p>
<h2 id="heading-utilise-the-right-tools">Utilise the right tools 🔧</h2>
<p>If you are building an API, use tools like <a target="_blank" href="https://www.getpostman.com/tools"><strong>Postman</strong></a> for checking the HTTP request/response and methods so that you can focus on validating your API first instead of other tasks.</p>
<p>If you are developing front end part first, then you can use some dummy texts like ‘<em>lorem ipsum'</em> for filling up dummy data in place of actual data, which will be later provided by the database when you start with the back-end. (For <a target="_blank" href="https://www.sublimetext.com/">Sublime Text</a>, typing <strong>lorem+TAB</strong> will automatically fill up dummy data).</p>
<p>If you have started web development and want to get some useful tips, tools and resources, do check this article - <a target="_blank" href="https://blog.neelvikmani.com/ultimate-web-development-tips-and-resources-c69ae1c04726"><strong>Web Development Tips and Resources</strong></a><strong>.</strong> This article also lists some tools and software which are very useful and productive.</p>
<h2 id="heading-got-bored-or-stuck-for-a-long-switch">Got bored or stuck for a long? Switch! 💫</h2>
<p>There may be times when you are working on the front end and feeling bored or stuck somewhere for too long. In such cases, you can switch to the backend and start developing the backend part of the application. This will make sure you are not blocked or your performance is not getting affected due to boredom working on one particular tech stack. After completing the backend part, you can resume your front-end work again. You will find yourself more productive this way and will be able to complete the project faster.</p>
<h2 id="heading-focus-on-code-maintainability-and-formatting">Focus on code maintainability and formatting</h2>
<p>This is a no-brainer for any developer. The code needs to be maintainable and in the proper format as per the language standards. This may not seem important initially when the application is small but when the application scales and grows in size, the features in the applications also increase and the lines of code increase at a very rapid scale.</p>
<p>If the code is not maintained over time, it might lead to more confusion and can be disastrous for your development journey. If the project is growing rapidly, make sure you have blocked dedicated time just for refactoring code and removing the lines of code which are not being used anymore. Also, add proper comments and test cases wherever required. This will surely help you in long run, if at all not in the beginning.</p>
<h2 id="heading-follow-proper-web-standards-and-focus-on-optimisations">Follow proper web standards and focus on optimisations 🌟</h2>
<p>Check if the basic things like input validation, authentication, authorization, and error handling are in place.</p>
<p>Make sure that the website you are building is compatible with different browsers which are common nowadays, like Chrome, Firefox, Safari, etc.</p>
<p>The website should also be developed with responsive design in mind so that it works and provides a consistent experience on different device sizes.</p>
<p>The application should be made in a way that will help in building the credibility of the website and also have good rankings in search engines. Try implementing various SEO techniques on the websites, for example: providing a readable slug for various pages, and having a valid tag for different content types like titles, headings, etc.</p>
<p>Optimize images which are used in websites. If the images are large enough, this can cause slowness in the website and can directly affect its rankings and usability. Use compressed images wherever possible, use SVG or WebP instead of png or jpeg, etc.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Managing all the things end-to-end can be overwhelming and also frustrating if it is not managed in the right manner. Hence avoiding some most common mistakes while developing web applications is a must and this article covers the steps you can follow to be better at developing web applications.</p>
<p>If you found this article helpful, please like, comment and share this article so that it reaches others. 😃</p>
<p>For more such content, please subscribe to my newsletter so that you get an email notification on my latest post. 💻</p>
<p>Let's connect 💫. You can follow me on</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/neel_vikmani">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/neelvikmani/">LinkedIn</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/hax0rr">GitHub</a></p>
</li>
</ul>
<p><a target="_blank" href="https://blog.neelvikmani.com/ultimate-web-development-tips-and-resources-c69ae1c04726">  
</a></p>
]]></content:encoded></item><item><title><![CDATA[Web Development for beginners]]></title><description><![CDATA[Before starting web development, I did a lot of research about how to get started, which are the latest technologies in this domain and then I started with the actual web development work. Initially, I started with front-end development and just deve...]]></description><link>https://neelvikmani.hashnode.dev/ultimate-web-development-tips-and-resources-c69ae1c04726</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/ultimate-web-development-tips-and-resources-c69ae1c04726</guid><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[software development]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Wed, 21 Dec 2022 13:46:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ca0da9863bd49763b7ac7353a2c4c455.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before starting web development, I did a lot of research about how to get started, which are the latest technologies in this domain and then I started with the actual web development work. Initially, I started with front-end development and just developed static web pages with some cool styling. But, when I started to dig deep into web development, I realized that there were many additional things that I needed to have my hands on.</p>
<p>Web development has a lot to things and mastering every concept of the web would take some time. From my initial years exploring web development, I have noted various points on the related topics, which I have shared in this article. Implementing all these points and tips will help you become a great web developer. At the end of this article, I have aggregated some resources that I have been using to be productive in various phases of web development.</p>
<p>I have mentioned topics in a sequential order <strong>which I followed</strong>, and I suggest you can do the same.</p>
<h2 id="heading-front-end-development">Front-end development</h2>
<p>Start with the basics of HTML and CSS. These are very simple and you can learn these technologies at <a target="_blank" href="https://www.w3schools.com">w3schools</a><strong>.</strong> Try to make simple static web pages using HTML and CSS. Understand the box model, class, ids, tags, transitions, transformations and media queries in CSS.</p>
<p>Once you are comfortable with CSS, start with <a target="_blank" href="https://getbootstrap.com">Bootstrap</a>. It is a front-end framework with the main focus on responsive, i.e. mobile-friendly web development. This will make your development faster and improve your efficiency for both desktop and mobile-based web development.</p>
<p>Now, start with <strong>Javascript</strong>. Understand the DOM, DOM manipulation using Javascript. Try to go through all the core concepts of Javascript.</p>
<p>Now, try to make simple projects like a ToDo App, any simple browser game using Javascript or a website with some cool transitions and animations.</p>
<h2 id="heading-back-end-development">Back-end development</h2>
<p>There are many technologies that you can use for back-end web development. I would suggest starting with Ruby on Rails / Node.js and <strong>MySQL</strong>. These technologies are very simple to understand and will help you in understanding the request/ response techniques in a web browser and how to interact with the database and back-end.</p>
<p><strong>Node.js</strong>, <strong>Express.js</strong> and <strong>MongoDB</strong> are more popular nowadays. One of the advantages of Node.js over PHP or RoR is that Node.js uses Javascript for the back-end as well, so you don’t need to learn a new programming language as you had used Javascript for front-end development. MongoDB is a NoSQL database, which stores data in documents and collections rather than tables(which MySQL uses). So exploring both databases will help you understand the structure of both types of databases.</p>
<p>Make projects that have very basic database requirements like signup and login functionality, and try to perform CRUD(create, read, update, delete) operations on some data using these technologies.</p>
<h2 id="heading-http-requestresponse-cookies-sessions-and-ajax">HTTP Request/Response, Cookies, Sessions and AJAX</h2>
<p>Once you are comfortable with basic front-end and back-end technologies, it’s time for you to jump to some advanced concepts on the web.</p>
<p>Explore server sessions, HTTP Requests and Responses, HTTP sessions and cookies. It will help you understand browsers, servers and how messages are sent from client to server and how the server processes those requests and sends responses.</p>
<p>Implement Ajax on your previously developed web application(that you developed with the back-end). Ajax is one of the most important concepts in web development. It will also broaden your knowledge of the request/response paradigm.</p>
<h2 id="heading-rest-apis-and-more">REST APIs and more</h2>
<p>As you get a clear idea about the HTTP request/response model, you can now try to build an API in a RESTful manner. RESTful APIs are used extensively in applications because of their statelessness, and understanding these technologies can help you get more exposure to various advanced topics and also help you during job interviews.</p>
<p>Try to implement simple E-commerce APIs which use HTTP methods to perform CRUD(create, read, update, delete) operations on products.</p>
<h2 id="heading-popular-frameworks">Popular frameworks</h2>
<p>Apart from trying out Laravel or Node.js, you can also try popular frontend frameworks like Angular, React, and Flutter for Web. This will help you understand concepts like stateful/stateless widgets, local storage, components, etc. React.js along with Node and Express.js is a very popular stack nowadays.</p>
<h2 id="heading-what-to-do-after-all-these-things">What to do after all these things?</h2>
<p>KEEP LEARNING!</p>
<p>Try some latest technologies</p>
<p>Don’t just stick to web development, try out mobile application development, read about system designs, explore machine learning, etc. It will widen your vision across various domains.</p>
<p>Do internships/ research.</p>
<p>Expand your network.</p>
<p>And finally, share your knowledge with others. :)</p>
<hr />
<p>Now, as promised, the following are some resource names that you will be requiring at various phases of web development. Make sure you save this so you don’t have to search at ten different areas and waste your time.</p>
<ul>
<li><p>IDE for web development — <a target="_blank" href="http://brackets.io">Brackets</a>, Sublime</p>
</li>
<li><p>UI Design Tools — <a target="_blank" href="https://www.invisionapp.com">Invision</a>, <a target="_blank" href="https://www.adobe.com/products/xd.html">Adobe XD</a></p>
</li>
<li><p>Icons — <a target="_blank" href="https://fontawesome.com">FontAwesome</a>, <a target="_blank" href="https://getbootstrap.com/docs/3.3/components/">Glyphicons</a>.</p>
</li>
<li><p>Fonts — <a target="_blank" href="https://fonts.google.com">Google Fonts</a></p>
</li>
<li><p>Colours — UIGradients, <a target="_blank" href="https://htmlcolorcodes.com">HTMLColorCodes</a>, <a target="_blank" href="https://flatuicolors.com">FlatUIColors</a></p>
</li>
<li><p>Stock Photos — <a target="_blank" href="https://unsplash.com">Unsplash</a>, <a target="_blank" href="https://www.pexels.com">Pexels</a></p>
</li>
<li><p>Illustrations — <a target="_blank" href="https://undraw.co">Undraw</a>, <a target="_blank" href="https://www.drawkit.io">Drawkit</a></p>
</li>
<li><p>Version Control — <a target="_blank" href="https://github.com">Github</a></p>
</li>
</ul>
<hr />
<p>I have pushed some projects on my <a target="_blank" href="https://github.com/hax0rr"><strong>Github</strong></a> account which you can check out.</p>
<p><em>You can follow me on</em> <a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a> <em>and</em> <a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a> <em>for more such articles or if you need any guidance.</em></p>
<hr />
]]></content:encoded></item><item><title><![CDATA[Freshers guide to prepare for Software Engineering  technical interviews]]></title><description><![CDATA[This article talks about how to prepare for technical interviews for SDE role as a fresher, and the lessons that I learned through my interview experiences as a fresher. It will help you understand how to start preparation so that you can get a good ...]]></description><link>https://neelvikmani.hashnode.dev/how-to-prepare-for-software-engineering-technical-interviews-as-a-fresher</link><guid isPermaLink="true">https://neelvikmani.hashnode.dev/how-to-prepare-for-software-engineering-technical-interviews-as-a-fresher</guid><category><![CDATA[interview preparations]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[Interview tips]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Neel Vikmani]]></dc:creator><pubDate>Thu, 13 Jun 2019 10:28:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/FCHlYvR5gJI/upload/v1669839174763/yCZzIOaf-.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article talks about how to prepare for technical interviews for SDE role as a fresher, and the lessons that I learned through my interview experiences as a fresher. It will help you understand how to start preparation so that you can get a good job offer at a product based company as a SDE / Software Engineer.</p>
<p>If you are looking for a job via college campus placements, companies usually start visiting colleges for hiring right from the start of the degree final year. Companies may have different requirements based on their job profile, packages, and engineering grades. I would suggest you to start planning and preparing for interviews atleast three months before the first job interview.</p>
<ol>
<li><p>Start solving <strong>aptitude</strong> questions. As you are a fresher, the companies generally conduct aptitude tests as a first round to filter out students based on some threshold of minimum marks in these tests. You may start solving aptitude questions on websites like <a target="_blank" href="https://www.indiabix.com">Indiabix</a>, as it has almost every basic topic of aptitude covered.</p>
</li>
<li><p>I believe that you must have solved some basic programming questions in college theory and practical assessments and have basic knowledge of programming languages such as C, C++, Java, etc. However, if you are not much into programming but want to get into a good company as a SDE, you still have good time. Pick any one of the above language and start going through the basics like data types, loops, function definition and declarations, program flow, etc. Geeksforgeeks is the best platform according to me for getting started and knowing the basics of language. For example: if you have picked Java, you can go through <a target="_blank" href="https://www.geeksforgeeks.org/java/">https://www.geeksforgeeks.org/java/</a>. It starts with the very basic concepts and goes all the way till advanced concepts like Multithreading, OOP using java, etc.</p>
</li>
<li><p>Start solving programming questions on <a target="_blank" href="https://leetcode.com">leetcode</a>. Start by solving easy level questions, and gradually move to medium level only when you are comfortable enough in solving easy questions. Practice daily for <strong>at least</strong> an hour so you get your basics cleared before your campus placements.</p>
</li>
<li><p>Thoroughly read through core topics such as OOP, databases, operating systems, and networking, and understand how various things work. Personally, I prefer <a target="_blank" href="https://www.geeksforgeeks.org">GeeksforGeeks</a> is the best website for understanding these concepts and you can get all the relevant topic related to Software Engineering there.</p>
</li>
</ol>
<h2 id="heading-data-structures-and-algorithms-dsa"><strong>Data Structures and Algorithms (DSA)</strong></h2>
<p>After you have picked up the language you are comfortable with, start understanding various data structures and algorithms. Again, <a target="_blank" href="https://leetcode.com">Leetcode</a> and <a target="_blank" href="https://www.geeksforgeeks.org">GeeksforGeeks</a> are the best websites I would recommend for getting good at DSA. Leetcode also has filters based on difficulty level or topics, which you can use to get started initially.</p>
<p>I have provided a list of data structure and algorithms below that you must know and practice before appearing for interviews. You can filter them in leetcode and try to solve problems one data structure/algorithm at a time, starting with easy level and moving to medium level questions once you are comfortable solving easy ones.</p>
<h3 id="heading-data-structures">Data structures</h3>
<ul>
<li><p>Arrays (1D and 2D Arrays)</p>
</li>
<li><p>Linked List (Single and doubly linked lists)</p>
</li>
<li><p>Stack</p>
</li>
<li><p>Queue(Simple, circular, priority and double-ended)</p>
</li>
<li><p>Trees(Binary Tree, Binary Search Tree, Heap structure and Trie)</p>
</li>
<li><p>Graphs</p>
</li>
<li><p>Hashing</p>
</li>
</ul>
<h3 id="heading-algorithms">Algorithms</h3>
<ul>
<li><p>Searching (Linear and Binary Search)</p>
</li>
<li><p>Sorting (Bubble, insertion, selection, quick, merge sort, etc.)</p>
</li>
<li><p>Recursion</p>
</li>
<li><p>Pattern searching</p>
</li>
<li><p>Graph Algorithms(BFS and DFS)</p>
</li>
<li><p>Greedy approach</p>
</li>
<li><p>Dynamic programming</p>
</li>
<li><p>Divide and Conquer</p>
</li>
<li><p>Backtracking</p>
</li>
<li><p>Analysis of algorithm (Big O)</p>
</li>
</ul>
<p>There are also many advanced data structures and algorithms, but the above listed are the most important ones that you should thoroughly understand first before moving on to advanced DSA.</p>
<h2 id="heading-build-projects">Build projects</h2>
<p>Most of you might already have worked on building projects throughout your engineering years. If you haven’t, try to build some good projects using various technologies.</p>
<p>Building projects does not mean making a very simple website or an application that would have built in a day or two, or any high-end project that has a thousand features in it. Just try to make something significant enough so you understand how the project development works in general and also try to explore some important concepts like MVC, APIs, etc. Learn about Git and start using git commands while making your projects.</p>
<p>If you have no idea what kind of projects to make, I would suggest learning technologies like Ruby on Rails or Node.js, Express.js, etc and make a web application using these technologies for starters.</p>
<blockquote>
<p><mark>I strongly believe that projects and internships are as important as learning and practicing data structures and algorithms.</mark></p>
</blockquote>
<p>Data structures and algorithms will help you in improving your problem-solving and debugging capabilities, and projects will help you gain confidence in building some real-world stuff and understanding the concepts which are commonly used in software development. Apart from that, it makes your resume look good and gives an impression that you have your hands on many technologies(not just DSA) and you are a self-starter.</p>
<p><strong>If you still have no idea about any topic for projects, here are some of the simple yet significant case studies and ideas I would suggest you can work on:</strong></p>
<ul>
<li><p>A news-based web application where admin can create and manage users and users can publish, edit or delete their news.</p>
</li>
<li><p>Making a RESTful API of an e-commerce website that facilitates CRUD(create, read, update, delete) operations on products and comments over products.</p>
</li>
<li><p>Developing a mobile application to manage your day to day events.</p>
</li>
<li><p>A chat-bot or any face recognition based application.</p>
</li>
</ul>
<h2 id="heading-learn-basics-of-system-design">Learn basics of System Design</h2>
<p>Companies might also have a round where they will ask you to design some system, like movie e-ticketing system, chat application, elevator system, etc. In this round, interviewer usually want to know your approach on building these systems.</p>
<p>The usual steps on approaching these kinds of questions are-</p>
<ol>
<li><p>Try to understand and note down the scope of the problem. Ask questions to clarify incase of any ambiguity.</p>
</li>
<li><p>Note down functional and non-functional requirements.</p>
</li>
<li><p>Start exploring and thinking on</p>
<ol>
<li><p>How end-users will interact with your system(ex: front-end UI),</p>
</li>
<li><p>How frontend will interact with backend(ex: using APIs),</p>
</li>
<li><p>How APIs will be designed(i.e. what will be request / response look like),</p>
</li>
<li><p>How will the data be stored in DB(i.e. what will be your db schema, what tables will you create, will you have any foreign keys, indexes, etc).</p>
</li>
</ol>
</li>
</ol>
<p>For this, you should know the basics about APIs, DBMS, OOPs, ER Diagrams, etc.</p>
<p>There are other things to think about as well, like-</p>
<ol>
<li><p>How will your system handle failures (ex: using resiliency, circuit breaker, etc)</p>
</li>
<li><p>How will your system handle scale ? (ex: increase read/write replicas of db, etc)</p>
</li>
<li><p>If your system includes booking or monetary transactions, how will you ensure strong consistency ? (ex: by using transactional db queries)</p>
</li>
</ol>
<p>If you are able to go through, understand and evaluate above concepts as well in your system design interview, then it would be a great deal.</p>
<p>Usually in system design interviews, there are other advanced topics as well but they are mostly expected from the experienced person who has worked on scalable products.</p>
<h2 id="heading-extra-curricular-activities">Extra-curricular activities</h2>
<p>Two to three months before your first interview is not the right time probably for starting to do some extracurricular activities, but if you haven’t done anything other than academics and technical profile, there are chances that the recruiter may not consider you an ideal candidate atleast as a fresher.</p>
<p>Companies want to hire people that are something more than just academics. If you were ever into any student or technical bodies of your college, or have been involved in any program outside college, have worked for an NGO, or have been into sports or any art, make sure you specify that in your resume as an extra-curricular activity.</p>
<p>If you haven't done anything yet, best way is to try to volunteer for some NGO or do some social work. You can mention this in your resume and it will help you in developing your personality and develop empathy as well :)</p>
<h2 id="heading-build-your-resume">Build your resume</h2>
<p>Ideally, your resume should be of one page and should highlight your education, work experiences(internships), projects, achievements, publications(if any) and extra-curricular activities.</p>
<p>Make your resume look professional, clean and crisp. Always have 3-4 copies of your resume handy during your interview. Also have a soft-copy in PDF and save as "RESUME_{NAME}", ex: RESUME_JOHN_DOE.pdf</p>
<h2 id="heading-prepare-the-commonly-asked-questions-in-advance">Prepare the commonly asked questions in advance</h2>
<p>There are some standard questions that will be asked in almost every company interview. Most of them are behavioural questions such as “Tell me about yourself”, "Tell me about situation where you had a tight deadline and how did you manage it", “Where do you see yourself in five years?”, “Why would you like to join this company?”, "How do you handle rejections" and so on.</p>
<p>Come up with the best and honest answers for such behavioral questions in advance. You don’t want to be a person who is unprepared for such frequent questions and make up a satisfactory answer during your interview.</p>
<blockquote>
<p>Always remember, your first impression can affect your image that the interviewer has, so make it the best.</p>
</blockquote>
<p>Also, <strong>research</strong> well about the company that you are going to apply for, and understand what they do, what technologies they use, any recent news like new funding round, etc and make a list of relevant questions about the company.</p>
<p>Usually, at the end of the interview, the interviewer asks whether you have any questions for them. Don’t ask obvious questions like “What does your company do?”, you should already know that. Ask something about their products and any current projects they are working on. This helps them know that you are genuinely interested in working with them.</p>
<h4 id="heading-during-your-interview">During your interview-</h4>
<ul>
<li><p>Wear proper formals clothes and shoes.</p>
</li>
<li><p>Greet your interviewer when you enter the room.</p>
</li>
<li><p>Always ask before you sit. (if at all it's an onsite interview ;) )</p>
</li>
<li><p>Make yourself comfortable and sit with a straight back.</p>
</li>
<li><p>Maintain eye contact with the interviewer and use proper body language when required.</p>
</li>
<li><p>Speak clearly and confidently.</p>
</li>
<li><p><strong>Most importantly,</strong> if you don’t know an answer, don’t try to fake it. It is always better to tell the interviewer that you don’t know the answer. They may not disqualify you if you don’t answer the question but faking an answer will surely make you disqualified.</p>
</li>
</ul>
<p>After the interview process is over, wait for the results. If you don’t get selected at a company, don’t be sad and lose hope.</p>
<blockquote>
<p><strong>“Don’t cry because it’s over, smile because it happened.”</strong> ― Dr. Seuss</p>
</blockquote>
<p>Try to understand where did you lack and what mistakes did you make.</p>
<p>Learn from your mistakes and work on improving it for the next interview. Tons of companies visit the campus for recruiting purpose and are out there, so actively apply for jobs at good companies and keep trying until you finally get selected.</p>
<hr />
<blockquote>
<p><strong>Do let me know in comments if this article helped you :)</strong></p>
<p>Also, please share this article on LinkedIn or Twitter or any preferred social netwok so that it can help others who are also preparing for interviews.</p>
<p>You can follow me on <a target="_blank" href="https://twitter.com/neel_vikmani"><strong>Twitter</strong></a> and <a target="_blank" href="https://www.linkedin.com/in/neelvikmani/"><strong>LinkedIn</strong></a> for more such articles or if you need any guidance or want to curate your resume.</p>
</blockquote>
]]></content:encoded></item></channel></rss>