<?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[The Synaptiq Blog]]></title><description><![CDATA[The Synaptiq Blog]]></description><link>https://alamba78.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 01 Nov 2026 06:29:56 GMT</lastBuildDate><atom:link href="https://alamba78.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Rethinking the Linux kernel with eBPF]]></title><description><![CDATA[Dynamically program the Linux kernel safely with eBPF]]></description><link>https://alamba78.hashnode.dev/rethinking-the-linux-kernel-with-ebpf</link><guid isPermaLink="true">https://alamba78.hashnode.dev/rethinking-the-linux-kernel-with-ebpf</guid><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[eBPF]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[bpf]]></category><dc:creator><![CDATA[Amit Lamba]]></dc:creator><pubDate>Thu, 23 Mar 2023 17:24:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1679591464157/e07413f0-9d4e-46f4-a518-3f78217c6a81.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>The Linux kernel is not directly programmable by non-core developers as any mistakes made with the kernel can lead to a system crash. But, there are times when we want a feature that isn’t in the kernel and hoping for the feature to be added might take many years: think of major kernel releases occurring after a minimum of 3+ years. This is generally a good thing as kernel stability and safety are paramount and it takes a lot of testing to introduce new features.</p>
<p>Kernel modules, which are used to develop device drivers for Linux, are an option to add programmability to the kernel, however, modules still pose a security and stability risk to the kernel as modules run with full kernel privileges. Testing the kernel module at the earliest stages of development is imperative, and even then vulnerabilities to kernel modules can be discovered much later by hackers. So, in the summer of 1990 Steven McCanne and Van Jacobson developed BPF–the Berkeley Packet Filter–or as it was announced in their official paper in December of 1992, the BSD Packet Filter. This allowed the Linux kernel to be dynamically programmable without kernel recompilation.</p>
<h3 id="heading-classic-bpf-cbpf">Classic BPF (cBPF)</h3>
<p>User space is the location from where normal user processes and user applications run. These processes can’t directly access the kernel space, although some parts of kernel space can be accessed via system calls. But, these system calls are limited in their scope and privileges. Kernel space manages applications and processes running in user space, provides the system call interface, is strictly reserved for running a privileged operating system kernel, provides kernel extensions and most device drivers, and provides controlled access to the underlying system hardware. Both kernel space and user space have their own unique memory address space that doesn’t overlap. This architecture is required to keep the kernel stable and secure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679584124302/8302ca24-bca5-48c6-93ef-8ef07f87f58f.jpeg" alt class="image--center mx-auto" /></p>
<p>The genesis for Classic BPF was due in part to the restrictions posed by the Linux system where network packet filtering had to be done in user space by copying the packets from the kernel space. This was a highly inefficient process. We did have application performance monitoring (APM) tools in user space that allowed for network troubleshooting, but those tools weren’t able to give minute details that the kernel would allow for. Where you might get network information in intervals of seconds with APMs, you can get information in intervals of milliseconds from kernel space, all while being close to the origin of the problem where you can investigate in novel ways. Classic BPF was proposed to allow you to develop programs that performed stateless packet filtering closest to the kernel and system hardware in kernel space. But, cBPF, at this stage, had a limited use case.</p>
<p>The second problem cBPF aimed to solve is the trust issue with kernel modules. Classic BPF, as it was initially conceived, eliminated trust issues by ensuring that BPF programs were highly restrictive in what they were allowed to do. The restrictions put in place for BPF programs, along with the rudimentary kernel verifier which statically analyzed the programs before loading them into the kernel, prevented programs from operating beyond their intended scope. You were only allowed to program in a restricted version of the C programming language, dereferencing pointers was not permitted, program instructions were not allowed to jump back or loop, there was an upper bound on the instruction count, programming was strictly typed, the use of only two 32-bit registers were permitted, memory was of a fixed size so there was no accessible memory stack, no global variables were permitted, no variadic functions were permitted, no floating-point numbers were permitted, etc. As you can see, it was a very restrictive environment and for good reason. Due to the limitations of the C programming language itself, that BPF programming was based on, and the advent of modern computer architectures, Classic BPF gave way to Enhanced BPF (eBPF).</p>
<h3 id="heading-enhanced-bpf-ebpf">Enhanced BPF (eBPF)</h3>
<p>In December of 2014, Alexei Starovoitov and Daniel Borkmann enhanced the BPF virtual machine within the Linux kernel with ten 64-bit registers, fall-through loops, the addition of key-value store maps for shared memory between user space and kernel space, a 512-byte stack, enabling easier JIT compilation of native BPF bytecode into platform-specific assembly instructions, helper functions, a new bpf function for syscalls, tail calls, an improved interpreter, and an improved verifier to check if eBPF programs are secure and stable.</p>
<p>eBPF programs are similar to kernel modules. Unlike kernel modules, however, eBPF programs don’t require you to recompile your kernel, and they are guaranteed to complete without crashing. Fundamentally, it allows user space programs to run in kernel space. They are loaded by the user process and automatically unloaded when the process exits. Each eBPF program is a safe run-to-completion set of instructions. The eBPF verifier statically determines that the program terminates and is safe to execute. During verification, the program takes a hold of maps that it intends to use, so selected maps cannot be removed until the program is unloaded. The program can be attached to different events. These events can be packets, tracepoint events and other types in the future. A new event triggers the execution of the program which may store information about the event in the maps. Beyond storing data, the programs may call into in-kernel helper functions which may dump stack, do trace_printk or other forms of live kernel debugging. The same program can be attached to multiple events and different programs can access the same map.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679590607333/0749a11f-2c36-4834-ae0a-4d00df33a9e6.jpeg" alt class="image--center mx-auto" /></p>
<p>These enhancements have allowed eBPF to outgrow the simple packet filtering purpose and are now used in kernel tracing, performance tuning, event monitoring, software-defined load balancing, firewalling, DDoS mitigation, cloud-native observability, stateful processing, and dynamic interactions with user space applications among other benefits. The interesting bit is that eBPF allows developers to safely and efficiently embed eBPF programs in any piece of software, not just the Linux kernel. These various use cases are being used across companies including Meta, Google, Microsoft, Isovalent (creators of Cilium), Netflix, Cloudflare, et al. Today, we now can refer to eBPF as just BPF as it has become the default standard even though cBPF is still used in tools like tcpdump.</p>
<h3 id="heading-bpf-to-the-future">BPF to the Future</h3>
<p>What started as the hard work of a few kernel developers has surpassed 200 contributors. There is still more to improve upon in this technology. As recently as 2020, a zero-day exploit allowed a bug in Linux’s BPF range analysis to pass and escalate the process privilege to root. But, this technology is being adopted readily as it allows developers to have much more power with their systems in a dynamic way to enhance the capabilities of the Linux kernel. As of now, only low-level languages can be utilized to program BPF programs in kernel space, such as C and Rust, as you use an LLVM, Clang, or GCC compiler. In user space, we can create BPF tools using high-level languages like Java, Python, Go, and Lua with BPF libraries. This opens up the possibilities to many more developers. Microsoft is even working on taking advantage of BPF to work on top of Windows. You will be hearing a lot about BPF and tools based on BPF in the future as it continues to mature.</p>
]]></content:encoded></item><item><title><![CDATA[The Power of SQL]]></title><description><![CDATA[Subqueries - Part 1]]></description><link>https://alamba78.hashnode.dev/the-power-of-sql-subqueries-part1</link><guid isPermaLink="true">https://alamba78.hashnode.dev/the-power-of-sql-subqueries-part1</guid><category><![CDATA[SQL]]></category><category><![CDATA[subqueries]]></category><category><![CDATA[PostgreSQL]]></category><dc:creator><![CDATA[Amit Lamba]]></dc:creator><pubDate>Thu, 09 Mar 2023 18:39:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678386325767/ec772c66-f79f-4319-8418-e40c8a7e68cb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-introduction">Introduction</h3>
<p>In the following series, we’re going to explore some of the intermediate to advanced techniques available to us when using an SQL or relational database. We’ll assume you have some basic experience with the Structured Query Language (SQL). As a baseline, you should have some basic experience with SQL and be aware of the SELECT and JOIN statements to follow along with this article. The examples that follow use syntax suited for PostgreSQL or MySQL databases.</p>
<p>When you have your data distributed among multiple tables, it makes sense that sometimes you need to combine or aggregate multiple tables together to extract meaning from your data. There are multiple ways this can be done. One way would be to JOIN tables together and filter using a WHERE clause. But, there are times when a simple JOIN isn’t the superpower you were looking for. When JOINing tables together, you’re only able to view multiple tables as one, but this may not be the most effective way to get information from your data. This just becomes a view of the data that you already have, which doesn’t help when you’re trying to learn from your data in a non-trivial way as part of data analysis or business intelligence. You can think of data without meaning as just measurements.</p>
<h3 id="heading-example-scenario">Example scenario</h3>
<p>Let’s set the stage for the following examples by providing an Entity Relationship Diagram (ERD) of the database we’ll be using.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678386417067/f7662435-8f26-44c4-9887-a6442b54ff31.jpeg" alt="ERD Diagram" class="image--center mx-auto" /></p>
<p>Here, we have two tables in our database. The first is the employees table and the second is the salaries table with the various fields listed for each table. As you can see, the two tables are related to each other with the emp_no as the Primary Key. In Part 1 of this series, we will only concern ourselves with the employees table. We’ll now proceed to the non-trivial question we want to answer.</p>
<p>The question we want to answer is: <strong><em><mark>How many employees have an age greater than the average age of all employees?</mark></em></strong></p>
<p>We’ll try to answer this question with a few different solutions. The very first naive solution may involve a simple SELECT query as such:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678386541257/af83cff9-e3d2-4b4b-be57-a2323504485f.jpeg" alt="naive SQL solution" class="image--center mx-auto" /></p>
<p>This statement will not work as the SQL engine will not allow you to use aggregate functions in a WHERE clause because the WHERE clause is used to filter data before aggregation. Ok, so we’ll just put the aggregate function into a HAVING clause instead since the HAVING clause allows for aggregation. That’s the difference between the WHERE and the HAVING clauses. So, our next naive solution might be this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678386663636/fbdb4fb2-eac0-45fb-9f51-1b712ca6d1d4.jpeg" alt="naive SQL solution #2" class="image--center mx-auto" /></p>
<p>Things get a little more interesting here. First, let me explain why there’s a GROUP BY clause in this statement as it’s very important to understand. When you use an aggregate function like AVG, any unaggregated fields in the SELECT clause must either be in the GROUP BY clause, or you have to use an aggregate function for each unaggregated field in the SELECT clause, or you can remove the unaggregated fields from the SELECT clause entirely. However, if we remove the name and age in our case, we won’t know who the employees are that have an age greater than the average age of all employees. You might be wondering why aggregation creates this problem for us. When you aggregate on a column, it means we are taking all the values of that column and summarizing it into a single value; the average of all ages of all employees in this case. So, SQL doesn’t know how to relate a single value result with multiple rows, unless we amend the SQL statement. There are other ways around this with a WINDOW function, but that’s a topic for another blog post. We also don’t want to aggregate on the name or age because we want to know each employee that has an age greater than the average age. So, we’re left with using a GROUP BY to prevent an error. Now that we’ve plugged in the GROUP BY, the above SQL statement is valid, but you won’t get any results! Any ideas why? Well, when you have an employees table with rows of name, birth date, etc, your table will contain unique rows. It doesn’t make sense to have duplicate entries in an employees table, since, as an individual, we only have one birth date or age. Keep in mind that this table has all unique rows, and none of the fields in our table can be logically aggregated and give us the answer to our original question. So, when you GROUP BY name and age in a table with all unique rows, there’s nothing to group! So, this SQL statement gives you an empty result–not the solution we were looking for!</p>
<h3 id="heading-subqueries-to-the-rescue">Subqueries to the rescue</h3>
<p>So, finally, we’ll attempt to answer our question with the use of Subqueries and the following SQL query:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1678386825865/facd849b-ad64-4bac-ad69-5289a3b063df.jpeg" alt="subquerie example " class="image--center mx-auto" /></p>
<p>Here, we have an SQL statement with the subquery shown with a blue bracket. You will notice how the subquery, also known as an inner query, is within the full query, which is also known as an outer query. This is why it has the name subquery as it’s a query within another query. Two things to consider when using subqueries are the placement of the subquery within the outer query and whether the subquery needs a dependency on the outer query as a correlated subquery, or as a simple subquery with no dependencies. Two factors dictate the placement of the subquery. The first is the problem you’re trying to solve and the other is the readability of the query. With regards to placement, there are four types of subqueries based on the placement within the outer query: WITH statement subqueries which are also called a Common Table Expression (CTE), nested or WHERE clause subqueries, inline subqueries found within the FROM clause which take the place of a table name and must be aliased, and scalar subqueries within the SELECT clause of the outer query where we select only one column or expression and return a single row. In our example SQL query above, you’ll notice we used a nested subquery as a simple subquery with no dependencies on the outer query.</p>
<p>All subqueries can stand alone as a valid SQL statement and they must be placed inside parenthesis. You can remove the outer query and just run the subquery (without parenthesis) and you’ll get the average age of all employees, in the case of our example SQL query. I would recommend this as the starting point when you think a subquery will be required to answer a question. Start with the subquery statement and make sure you get the correct results as part of the final solution. We know we have to calculate the average age. Now that we have the average age, we can use this result in a WHERE clause and get the name and age of all employees from the outer query that satisfies the WHERE clause. In this situation, you don’t need to use a GROUP BY or aggregate the unaggregated fields in the SELECT clause of the outer query because the AVG function is not part of the outer query. You also don’t need a HAVING clause for the same reason–there is no aggregate function in the outer query. The WHERE clause will only see the result of the subquery and SQL will not complain.</p>
<p>Understanding when a subquery might be of use and where best to place the subquery takes practice, as it seems foreign at first. Although the question we solved in this post was fairly straightforward, subqueries are quite powerful as you can use multiple subqueries in a single SQL statement, use them in conjunction with JOINing tables, or introduce a subquery using another type of placement. Even the nested query we have shown can be part of a complex query based on the problem at hand. Part 2 of this series will dive into some of the other subquery placement types. Until then, I hope this helped or put light on the irreplaceable power of SQL.</p>
]]></content:encoded></item><item><title><![CDATA[The DevOps, SRE, and Platform Engineering Evolution]]></title><description><![CDATA[DevOps has given rise to new roles that continue to follow the DevOps philosophy. Think of this as a natural evolution of DevOps rather than revolution.]]></description><link>https://alamba78.hashnode.dev/the-devops-evolution</link><guid isPermaLink="true">https://alamba78.hashnode.dev/the-devops-evolution</guid><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[Devops]]></category><category><![CDATA[SRE]]></category><category><![CDATA[Platform Engineering ]]></category><dc:creator><![CDATA[Amit Lamba]]></dc:creator><pubDate>Wed, 08 Feb 2023 10:52:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1675852330496/9a29d8bf-b076-4239-8457-8a8c4ccdfcbb.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-what-devops-is"><strong>What DevOps Is</strong></h1>
<p>Around the year 2007, a systems architecture consultant named Patrick Debois was frustrated with the incongruence between developers and operations teams. It was during this time that he was trying to formulate a better way for developers and operations teams to work more symbiotically. A few years later, John Allspaw and Paul Hammond gave a talk at the 2009 O’Reilly Velocity Conference called “10+ deploys per day: dev and ops cooperation at Flickr.” The Velocity Conference brings together engineers focused on exchanging ideas about what works best when building and maintaining complex cloud-native and hybrid systems. It was with this talk that Patrick was able to resonate with the issues revolving around getting dev and ops to work harmoniously towards a common goal. After the 2009 Velocity Conference, Patrick organized a conference called DevOps Days in Belgium of the same year, where the entire conference was dedicated to sharing hard-won lessons in the pursuit of a better way for dev and ops to work together. It was after these two conferences that the term and philosophy of DevOps were formalized and eventually iterated to become what it is today.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675850935234/b202789d-e304-4ec4-b2e3-12650ac0cfa3.jpeg" alt class="image--center mx-auto" /></p>
<p>DevOps has roots in the Agile methodology, which has its roots in the Lean Manufacturing movement. DevOps focuses on maximizing efficiency, identifying programmable processes, and increasing automation. Agile has a fail-fast mindset while centering around adaptability and keeping pace with customer needs. The DevOps philosophy helped solve the issue of dev, ops, security, QA, and testing teams still working in silos, which wasn’t addressed by the Agile methodology. But, using an amalgamation of both philosophies has made tremendous strides from the days of the waterfall methodology. Teams that practice DevOps ship better work faster, streamline incident responses, and improve collaboration and communication across teams.</p>
<h1 id="heading-what-devops-isnt"><strong>What DevOps Isn’t</strong></h1>
<p>Let’s get straight to the point–DevOps is not a role or a position. No matter how many times you see ‘DevOps Engineer’ in job postings, it is a play on the hype surrounding DevOps. The job description lists the responsibilities a Solutions Architect or a traditional Systems Administrator would carry out–with a more cloud-centric focus. DevOps is a culture, a philosophy, and a way of organizing and executing processes. These philosophies can be adhered to by dev, ops, testing, QA, and security engineers working as cross-functional teams.</p>
<p>However, the evolution of DevOps has opened the door to new specialized roles: Site Reliability Engineer (SRE) and Platform Engineer.</p>
<h1 id="heading-site-reliability-engineer-sre"><strong>Site Reliability Engineer (SRE)</strong></h1>
<p>The term Site Reliability Engineer (SRE) was coined by Ben Treynor Sloss, the VP of Engineering at Google. Some people mistakenly assume SRE is DevOps 2.0, but this is not true. DevOps as a philosophy, allows organizations to deploy applications faster, which results in a more optimized application lifecycle. SRE, on the other hand, is about optimizing the reliability and availability of systems, sites, and running applications. So, site reliability follows the principles of DevOps to accomplish its task.</p>
<p>Before the advent of cloud service providers, organizations relied on system administrators to deploy software and manage data centers. These responsibilities included setting up storage, networking, security, backups, etc. These are responsibilities we now associate with operations. While, software developers were responsible for, well, developing software. Today, with cloud environments, everything is a software problem with a software solution. The goal of an SRE is to keep our applications available and reliable as much as possible through software solutions with automated processes and observability. This fits in with the DevOps mindset. Therefore, an SRE is not DevOps 2.0, but a specialized part of the DevOps philosophy. You could say that SRE is a specialized evolution of doing operations. Previously, operations were done in a particular way that may not have always led to satisfactory results. SRE incorporates a more software engineering aspect to operations and infrastructure problems, but still adheres to the DevOps principles.</p>
<p>You can think of the relationship between the DevOps philosophy and the role of an SRE like our fancy cars today: all the engineering behind keeping our cars moving from point A to point B is DevOps, while the sensors that notify the driver that the car is drifting out of the driving lane is site reliability. In essence, site reliability ensures our applications continue to run and course corrects when the unexpected happens. Now, what is a Platform Engineer? How does that role fit into the DevOps philosophy? I’m glad you asked.</p>
<h1 id="heading-platform-engineer"><strong>Platform Engineer</strong></h1>
<p>A Platform Engineer is another specialized role that is part of the DevOps philosophy of automating and delivering applications in a faster and repeatable fashion. They improve the developer experience and developer productivity by providing reusable autonomous service capabilities, such as tools and workflows to automate parts of the infrastructure without the operation team’s involvement. An example tool could be a CLI that allows the developer to create separate dev, stage, and production servers. An example workflow could include a source control system connected to a continuous integration system, along with a way to deploy assets into production.</p>
<p>Platform engineering is found in large organizations with complex application lifecycles. The platform engineer creates and centrally manages reusable tools and workflows which the developers use to do their job. You can think of these resources like using Canva. Canva provides templates, tools, and resources to create design assets that would otherwise be more difficult to create using Adobe Photoshop, as Photoshop expects you to start from a blank canvas. This is similar to the benefits that platform engineers provide developers. It allows developers to accelerate the delivery of applications and provide faster business value through the use of centrally managed tools and workflows allowing developers to act fast and independently through established systems.</p>
<h1 id="heading-the-devops-evolution"><strong>The DevOps Evolution</strong></h1>
<p>The new roles that DevOps has created, address the challenges of doing DevOps at scale by aligning developer practices with business values and reducing the complexity of modern software lifecycles. DevOps is a broad movement that began with a focus on eliminating traditional silos between development and operations. While we have new roles within DevOps, they are intended to allow more interoperability between teams rather than create new silos. The new roles are an evolution of DevOps, rather than a revolution.</p>
]]></content:encoded></item><item><title><![CDATA[From O(no) to Big O(n)]]></title><description><![CDATA[Tackle your fears and learn data structures and algorithms one step at a time.]]></description><link>https://alamba78.hashnode.dev/stop-worrying-and-learn-dsa</link><guid isPermaLink="true">https://alamba78.hashnode.dev/stop-worrying-and-learn-dsa</guid><category><![CDATA[algorithms]]></category><category><![CDATA[data structures]]></category><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[Problem Solving]]></category><dc:creator><![CDATA[Amit Lamba]]></dc:creator><pubDate>Thu, 02 Feb 2023 02:26:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674563291173/c1fedb2b-39e0-4e7c-ac0d-43d396be40d4.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-the-dilemma">The Dilemma</h3>
<p>Have you contemplated learning Data Structures and Algorithms (DSAs) in the past? Did you half-heartedly try to learn it but thought it wasn’t possible? Maybe you convinced yourself that you don’t need to learn it. “It’s too hard and my job doesn’t require me to know this”, you say. Maybe that’s true and you don’t need it for your <em>current</em> job, but in a time of recession where we see massive layoffs in the IT field, it wouldn’t hurt to have some extra tools in your tool belt to give you options. David Epstein stated it best in his book <em>Range</em>, when he said, “mental meandering and personal experimentation are sources of power…”</p>
<p>There's a little-known secret about the legendary tennis player, Andre Agassi: he <em>hated</em> tennis. Specifically, he hated to practice, but he did it anyway. He wanted to quit–which he almost did many times growing up–yet he always came back to the game. It's the same feeling I had with learning DSAs. You hate it for a while, and then you learn to embrace it. At some point, if you keep at it, you'll experience a breakthrough. This doesn't mean you have to grit and grind through frustration and put yourself through mental stress. No, that's not the way. Take your time with it by taking it one day at a time, as consistency is the most important factor in achieving things we set our minds to. The best way to alleviate some of the pressure and keep your motivation from waning is to see it as a process, stop focusing on the goal, and find the right type of learning material that suits you.</p>
<p>For a minute, imagine yourself in the not-too-distant future having learned DSAs and conquered your demons. How do you feel? Relieved? Accomplished? Proud, even?</p>
<h3 id="heading-the-mindset">The Mindset</h3>
<p>As children, we are intrepid in our pursuit to learn new things; we’re always full of curiosity and wonder about our new world. Why is this? I believe children have a mindset to experiment because they don’t set limitations on their wonder. They don’t understand the concept of failure at that young age and only want to experiment and satisfy their curiosity. As adults, we allow feelings of doubt, fear, and judgment to permeate our minds and cripple our sense of wonder and what we think we can accomplish.</p>
<p>Thomas Edison was famous for his dogmatic pursuit of inventing the light bulb. I’m sure you’ve all heard his thoughts on his journey of discovery: “I have not failed, I’ve just found 10,000 ways that won’t work.” This is the growth mindset that Carol Dweck so lucidly explained in her book, <em>Mindset</em>. In the book, she proclaims, “In the fixed mindset, everything is about the outcome. If you fail—or if you’re not the best—it’s all been wasted. The growth mindset allows people to value what they’re doing <em>regardless of the outcome</em>. They’re tackling problems, charting new courses, working on important issues. Maybe they haven’t found the cure for cancer, but the search was deeply meaningful.”</p>
<p>Setbacks are an asset for a growth mindset because it sets the stage to try something in a new, innovative way. It nudges us to get back up and go for it again–but only if we have a growth mindset and understand that it’s okay to stumble, but it’s not okay to quit. As Ryan Holiday so eloquently put it in <em>The Obstacle is the Way</em>, “The obstacle in the path becomes the path. Never forget, within every obstacle is an opportunity to improve our condition.” Read that again–the obstacle <em>in</em> the path <em>is</em> the path. Obstacles are inevitable, conquering them is how you move forward. So, avoiding obstacles and stopping at the first sign of them, should never be an option. The difference between consistently showing up and giving up is the process and mindset you set for yourself.</p>
<p>We also need to stop looking ahead at our colleagues who are further along in the journey and feel dubious of our abilities. This is imposter syndrome. It’s an imposter because it’s an existential crisis that only exists in our minds. These kinds of thoughts are normal when we set out for the unknown to learn something new. Understand that everyone starts from zero. These self-sabotaging beliefs and the rat race of competition don’t serve us in any way to achieve our goal. The only person you have to compete with is the future version of yourself. So, be intentional in your process, focus on what you control, set smaller victories, enjoy the journey, and always be moving forward. Success is not about focusing on the goal; the goal is only a device we use to set our path. Real success comes while following the journey.</p>
<blockquote>
<p><strong>Success is not about focusing on the goal; the goal is only a device we use to set our path.</strong></p>
</blockquote>
<h3 id="heading-the-way-forward">The Way Forward</h3>
<p>With intent and consistency, the human mind can accomplish great things. Some people learn through reading, some through videos, and some through mentorship. If you’re having a hard time understanding AVL Trees or Tries, maybe all you need is another analogy or another perspective from a different source. The main thing is to be kind to yourself by being patient and finding what works and what doesn't.</p>
<p>It’s rarely the case where we set out to achieve a goal and follow a linear path. Achievements are fraught with detours, obstacles, adjustments, and challenges. But, this is the way. This is part of your hero’s journey. Let the obstacle be the way and slay your dragons. When we’re stuck trying to solve an algorithm problem, we have to find shortcuts to overcome these setbacks. It’s not always hard work and grind that wins. Many times it’s understanding that one way doesn’t work so we need to find an alternative way. That may be through watching a Youtube video, learning from a book, asking for help, and sometimes even taking a break. Richard Feynman said, “Study hard what interests you the most in the most undisciplined, irreverent, and original manner possible.” By finding shortcuts and detours in your search for knowledge, you will keep the well of interest and curiosity full.</p>
<blockquote>
<p><strong>Let the obstacle be the way and slay your dragons.</strong></p>
</blockquote>
<h3 id="heading-letting-go">Letting Go</h3>
<p>Is it necessary to always grind and move forward with a learning experience? No–there are times when our careers, interests, or motivations change. But, that should only be an option when you have something else to chase. Walking away should never be an option because of our insecurities. Once you allow your insecurities to take control, you’ll be surprised how many times they derail your future endeavors. Letting go should only be a viable option when there’s a legitimate reason. We are ever-evolving and our circumstances evolve as well, so I won’t say that you must complete everything you start.</p>
<p>Science has also shown that we engage in puzzles, video games, and hard tasks for that ‘A-ha!’ moment. It’s a special feeling of accomplishment. This feel-good sensation is the result of a hormone in our body called Dopamine. Dopamine is a messenger hormone responsible for reward processes in our minds. It’s the same hormone involved when we eat good food, earn money, and have sex. According to Christian Windischberger, one of the researchers investigating how the brain reacts to these ‘A-ha!’ sensations, “Our results indicate a close correlation between dopamine, exhilaration, and creativity.” This shows that solving problems is something we’re wired to enjoy and increases our ability to solve new problems in innovative ways. Without the struggle, there wouldn’t be an exhilarating reward.</p>
<h3 id="heading-productive-mastery">Productive Mastery</h3>
<p>Some tips that I have used in my journey of struggle may come to work for you as well. Here, I share some tips and resources that have served me well:</p>
<ul>
<li><p>Learn for yourself and your curiosity, and not for school or a job.</p>
</li>
<li><p>The goal will take care of itself if you consistently show up. So, set an achievable goal with smaller milestones for early wins.</p>
</li>
<li><p>Be intentional in your journey by having a partner or a group to learn with.</p>
</li>
<li><p>Don’t just have a goal, visualize what achieving that goal would mean.</p>
</li>
<li><p>Learn every day, however small it may be. Enter that into a calendar and watch how hard it will be to break your string of commitments. This is habit tracking.</p>
</li>
<li><p>Don’t add pressure by only prepping for an interview. Start early and study because you’re curious and have a purpose for learning DSAs. The urgency of getting ready for a job interview adds too much stress by putting you on a tight schedule. Some people do work better under pressure, but it's a lot less stressful if you start before it becomes a crucial part of obtaining something you value.</p>
</li>
<li><p>Understand that it will be hard sometimes and there may be days when you feel exhausted. It’s ok, take a break if you need to or tackle a smaller problem. Never lose hope.</p>
</li>
<li><p>Reverse engineer your algorithms study when stuck by looking at the solution on Leetcode or a GitHub repository. It’s not cheating, it’s a shortcut as long as you understand the solution. Come back to it in a couple of days and try to solve the problem yourself. This hack could be used the entire time as a way to learn faster rather than toiling away trying to figure out the solution on your own. Remember, study in the most undisciplined, irreverent, and unique way possible. Don’t get stuck in a rut and get discouraged.</p>
</li>
<li><p>The majority of technical whiteboarding questions come from medium-level Leetcode problems. Spend time wisely on the easy to medium-level questions and only look at the really hard ones if it interests you.</p>
</li>
<li><p>Don't tackle Leetcode questions by filtering them by the data structure used. Mix it up and see if you know which data structure/algorithm to use.</p>
</li>
<li><p>Don’t memorize the problem, data structure, and algorithm used. Learn the patterns to solve similar problems. This way when the problem is slightly different, you won’t get stuck.</p>
</li>
<li><p>Teach what you’re learning to someone else in the simplest way possible or take notes in your own words to get comfortable with the subject matter. This is the famous Feynman Method.</p>
</li>
<li><p>Be comfortable in at least one or two programming languages. I would recommend Python and supplement that with any C-style language like Java or C++. At the very least, you should be comfortable reading code in Java or C++, if you don’t intend to be fluent.</p>
</li>
<li><p>Use the Pomodoro technique to study in 25-minute chunks. Don’t burn yourself out.</p>
</li>
<li><p>Understand that your energy levels are more important to your study than the amount of time you spend toiling away. Eat well, be active, take breaks, drink water, stay connected to your friends, and sleep well.</p>
</li>
<li><p>Keep distractions away by keeping devices away. Learn deeply or don’t learn at all.</p>
</li>
</ul>
<p>Remember that our minds are capable of learning things when we persist. Don’t just be someone–become someone. Strive to be slightly better than the previous day.</p>
<hr />
<h3 id="heading-resources">Resources:</h3>
<p>Books (full disclosure: these have affiliate links)</p>
<p>I would suggest any two of these books and I have purposely selected ones that don't delve into higher mathematics and theory.</p>
<ul>
<li><p><strong><em><mark>Grokking Algorithms by Aditya Bhargava</mark></em></strong> <em>(full disclosure: I was one of the early reviewers of this book while it was being written). There is a Second Edition of this in the works. This is a good introductory book on the subject and very fun to read.</em></p>
<p>  <a target="_blank" href="https://www.manning.com/books/grokking-algorithms?utm_source=synaptiq&amp;utm_medium=affiliate&amp;utm_campaign=affiliate&amp;a_aid=synaptiq">Buy on Manning</a></p>
</li>
<li><p><strong><em><mark>A Common Sense Guide to Data Structures and Algorithms, Second Edition by Jay Wengrow</mark>*</em></strong>. This dives deeper into the subject and is a good book to follow Grokking Algorithms. The author makes learning the subject very approachable.*</p>
<p>  <a target="_blank" href="https://amzn.to/3DcAkcP">Buy on Amazon</a></p>
</li>
<li><p><strong><em><mark>Guide to Competitive Programming, Second Edition by Antti Laaksonen</mark></em></strong>. This is a very unique book that delves into the competitive programming arena, but it’s a really good book to learn Data Structures and Algorithms in C++. Some people say this book is better than the <em>Introduction to Algorithms</em> book by CLRS because it’s not heavy into mathematical proofs and theory.</p>
<p>  <a target="_blank" href="https://amzn.to/3XAMc0C">Buy on Amazon</a></p>
</li>
</ul>
<p>Honorable Mentions (recommended but ranked below my top 3)</p>
<ul>
<li><p><strong><em><mark>Cracking the Coding Interview, Sixth Edition by Gayle Laakmann McDowell</mark>*</em></strong>. A book that most of us have heard of and seen recommended many times. But, if you follow any two of the above, I don’t think you need this one. But, it’s a personal call on what programming languages you are comfortable with and which teaching style you prefer. This book goes into more than just Data Structures and Algorithms.*</p>
<p>  <a target="_blank" href="https://amzn.to/3wChW9u">Buy on Amazon</a></p>
</li>
<li><p><strong><em><mark>Elements of Programming Interviews in Python by Adnan Aziz, Tsung-Hsien Lee, et al</mark></em></strong>. A great book for those who are comfortable with Python programming. But again, if you have any two of the top three, this probably isn’t needed. But, if you want a book on more than just Data Structures and Algorithms, then any of these two honorable mentioned books would be great.</p>
<p>  <a target="_blank" href="https://amzn.to/3WzTvnW">Buy on Amazon</a></p>
</li>
</ul>
<p>Courses (full disclosure: some of these have affiliate links)</p>
<p>Paid</p>
<ul>
<li><p><strong><mark>Back to Back SWE</mark></strong></p>
<p>  This course is taught by an engineering student in a friendly and enthusiastic way. It's like having a mentor by your side going through a rigorous college-level curriculum on DSAs. I wholeheartedly recommend this course. You can sign-up for a subscription for 6 months, 1 year, or lifetime. The course usually comes with a discount every so often, so I would look to see if there's a promo going on right now. Also, you can use <strong>synaptiq</strong> as a promo code to get an additional 10% off and stack it on top of any running promos.</p>
<p>  <a target="_blank" href="https://backtobackswe.com/pricing">Link to Paid Course</a></p>
</li>
<li><p><strong><mark>Design Gurus Grokking the Coding Interview: Patterns for Coding Questions</mark></strong></p>
<p>  Having a trove of patterns that correlate to problem-solving techniques sets this course apart. Recognizing patterns for DSA problems gives you superpowers as it allows you to remove the window dressing in tough questions, understand the heart of the problem, and recognize the optimal solution.</p>
<p>  <a target="_blank" href="https://designgurus.org/link/GG2bHz?url=https%3A%2F%2Fdesigngurus.org%2Fcourse%3Fcourseid%3Dgrokking-the-coding-interview">Link to Paid Course</a></p>
</li>
</ul>
<p>Free</p>
<ul>
<li><p><strong><mark>Best Data Structures &amp; Algorithms (DSA) Course - Clear Any FAANG Interview</mark></strong></p>
<p>  <a target="_blank" href="https://www.youtube.com/watch?v=rZ41y93P2Qo&amp;list=PL9gnSGHSqcnr_DxHsP7AW9ftq0AtAyYqJ">Link to Free Course</a></p>
</li>
<li><p><strong><mark>FreeCodeCamp (w/ Teamtreehouse)</mark></strong></p>
<p>  <a target="_blank" href="https://www.freecodecamp.org/news/algorithms-and-data-structures-free-treehouse-course/">Link to Free Course</a></p>
</li>
<li><p><strong><mark>FreeCodeCamp (w/ Jovian)</mark></strong></p>
<p>  <a target="_blank" href="https://www.freecodecamp.org/news/learn-algorithms-and-data-structures-in-python/">Link to Free Course</a></p>
</li>
</ul>
<p>Forums</p>
<ul>
<li><p>Reddit</p>
<p>  r/leetcode</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>