<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Micah Kepe</title>
    <description>The latest articles on DEV Community by Micah Kepe (@micahkepe).</description>
    <link>https://dev.to/micahkepe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1485655%2Fe552f617-5f19-4cb4-bb93-4c4ea837f456.png</url>
      <title>DEV Community: Micah Kepe</title>
      <link>https://dev.to/micahkepe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/micahkepe"/>
    <language>en</language>
    <item>
      <title>I Made an Extended Version of vimtutor - Introducing Vimtutor Sequel</title>
      <dc:creator>Micah Kepe</dc:creator>
      <pubDate>Sat, 03 Aug 2024 14:12:48 +0000</pubDate>
      <link>https://dev.to/micahkepe/i-made-an-extended-version-of-vimtutor-introducing-vimtutor-sequel-8in</link>
      <guid>https://dev.to/micahkepe/i-made-an-extended-version-of-vimtutor-introducing-vimtutor-sequel-8in</guid>
      <description>&lt;p&gt;Hey DEV community,&lt;/p&gt;

&lt;p&gt;I'm excited to share something I've been working on - &lt;strong&gt;Vimtutor Sequel&lt;/strong&gt;! 🎉&lt;/p&gt;

&lt;p&gt;After going through the original &lt;code&gt;vimtutor&lt;/code&gt;, I felt there was a need for an extended tutorial for some more advanced topics not covered in the original tutor program.&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Vimtutor Sequel?
&lt;/h1&gt;

&lt;p&gt;Vimtutor Sequel picks up where the original &lt;code&gt;vimtutor&lt;/code&gt; left off. It’s designed for those who already know the basics and are ready to dive into more advanced Vim features and commands.&lt;/p&gt;

&lt;h1&gt;
  
  
  Key Features
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Topics&lt;/strong&gt;: Dive into splits, spellcheck, advanced search and replace, macros, Vim scripting, plugins, sessions, and registers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-Step Tutorials&lt;/strong&gt;: Hands-on lessons that encourage you to practice commands as you learn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Vim Configuration&lt;/strong&gt;: Comes with a custom vimrc to ensure a consistent learning experience and mimic the original &lt;code&gt;vimtutor&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How to Install
&lt;/h1&gt;

&lt;h2&gt;
  
  
  For Mac
&lt;/h2&gt;

&lt;p&gt;To get started, install Vimtutor Sequel using Homebrew:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install vimtutor-sequel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  How to Use
&lt;/h3&gt;

&lt;p&gt;To start the Vimtutor Sequel lessons, just run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vimtutor-sequel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  For Windows/Linux
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the repository&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/micahkepe/vimtutor-sequel.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigate to the repository&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;vimtutor-sequel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make a Copy of the Tutorial&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;vimtutor-sequel.txt vimtutor-sequel-copy.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run Vim with the Custom Configuration&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim &lt;span class="nt"&gt;-u&lt;/span&gt; vimtutor-sequel.vimrc vimtutor-sequel-copy.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Looking for Feedback!
&lt;/h1&gt;

&lt;p&gt;I'd love to hear what you think! Whether you spot any bugs, have suggestions for new lessons, or just want to share your thoughts, your feedback is really appreciated. Feel free to contribute or open issues on the GitHub repo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Links
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/micahkepe/vimtutor-sequel" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/micahkepe/vimtutor-sequel/issues" rel="noopener noreferrer"&gt;Issues &amp;amp; Feedback&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for checking it out, and I hope you find it useful in your Vim journey. Happy Vimming! 🚀&lt;/p&gt;

</description>
      <category>vim</category>
      <category>commandline</category>
      <category>tutorial</category>
      <category>psa</category>
    </item>
    <item>
      <title>Bloom Filters: Space-Efficient Probabilistic Data Structures</title>
      <dc:creator>Micah Kepe</dc:creator>
      <pubDate>Sat, 03 Aug 2024 14:11:19 +0000</pubDate>
      <link>https://dev.to/micahkepe/bloom-filters-space-efficient-probabilistic-data-structures-11od</link>
      <guid>https://dev.to/micahkepe/bloom-filters-space-efficient-probabilistic-data-structures-11od</guid>
      <description>&lt;p&gt;In the realm of computer science, efficiency is often the key to solving complex problems. One elegant solution that stands out for its efficiency is the Bloom filter. Despite being relatively lesser-known, Bloom filters offer a powerful method for determining set membership while using minimal space. This post explores what Bloom filters are, how they work, their applications in various fields, and compares them with other data structures.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(&lt;/em&gt;&lt;em&gt;Note&lt;/em&gt;&lt;em&gt;: this article was originally published in its entirety with the code snippets for the experiments on my blog: check it out &lt;a href="https://micahkepe.com/blog/bloom-filters/" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Bloom Filter?
&lt;/h2&gt;

&lt;p&gt;A Bloom filter is a probabilistic data structure designed to efficiently test whether an element is a member of a set. It can tell you if an element is definitely not in the set or that it might be in the set. This probabilistic nature makes Bloom filters incredibly space-efficient, but it also means they come with a small chance of false positives.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friscxjg6kuvivgzkbuce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Friscxjg6kuvivgzkbuce.jpg" alt="Bloom filter" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Bloom filter consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A bit array of size &lt;strong&gt;m&lt;/strong&gt; (initially all bits are set to 0).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;k&lt;/strong&gt; independent hash functions, each of which maps an element to one of the $m$ array positions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Bloom Filters Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Insertion
&lt;/h3&gt;

&lt;p&gt;To add an element to the Bloom filter, the element is passed through each of the &lt;strong&gt;k&lt;/strong&gt; hash functions, resulting in &lt;strong&gt;k&lt;/strong&gt; array positions. The bits at these positions in the bit array are set to 1. If any of these bits are already set to 1, they remain unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Querying
&lt;/h3&gt;

&lt;p&gt;To check if an element is in the Bloom filter, the element is hashed using the same &lt;strong&gt;k&lt;/strong&gt; hash functions to find the $k$ array positions. If all the corresponding bits in the bit array are 1, the Bloom filter reports that the element might be in the set. If any of the bits are 0, the element is definitely not in the set.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Positives
&lt;/h3&gt;

&lt;p&gt;Bloom filters do not store the actual elements, so they can never have false negatives (i.e., reporting an element is not in the set when it actually is). However, they can have false positives (i.e., reporting an element is in the set when it is not). The probability of false positives depends on the size of the bit array &lt;strong&gt;m&lt;/strong&gt;, the number of hash functions $k$, and the number of elements inserted &lt;strong&gt;n&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mathematical Insight
&lt;/h2&gt;

&lt;p&gt;The false positive probability $p$ can be approximated by:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;p≈(1−(1−1m)kn)kp \approx \left(1 - \left(1 - \frac{1}{m}\right)^{kn}\right)^k &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;≈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size4"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;kn&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size4"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;For practical use, choosing the optimal number of hash functions $k$ and the bit array size $m$ is crucial to minimize the false positive rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing a Bloom Filter with a Hash Set in Python
&lt;/h2&gt;

&lt;p&gt;To demonstrate the practical use of Bloom filters, let's consider a mock scenario where a Bloom filter is used to check if a URL is malicious. We will compare Bloom filters and hash sets in terms of space efficiency and the ability to quickly determine if a URL is in the blacklist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mock Scenario: Checking Malicious URLs
&lt;/h3&gt;

&lt;p&gt;In this scenario, we simulate a web browser that checks if a URL is malicious using a locally stored Bloom filter or list. The Bloom filter offers a space-efficient solution, reducing the need for frequent network calls.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bloom Filter&lt;/strong&gt;: Efficient in terms of space, but can have false positives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash Set&lt;/strong&gt;: No false positives, but can be memory-intensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup and Explanation
&lt;/h3&gt;

&lt;p&gt;We will simulate a scenario where we have 1 million URLs in a blacklist and check a large number of URLs to see if they are malicious. This will highlight the space efficiency of Bloom filters compared to hash sets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bloom Filter
&lt;/h3&gt;

&lt;p&gt;Here's the results I got when running the Bloom filter simulation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bloom Filter Insertion Time: 3.457702159881592 seconds
Bloom Filter Query Time: 0.10877871513366699 seconds
False Positives: 121
Memory Usage: 1.14 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hash Set
&lt;/h3&gt;

&lt;p&gt;Here's the results I got when running the hash set simulation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hash Set Insertion Time: 0.6073956489562988 seconds
Hash Set Query Time: 0.03299856185913086 seconds
False Positives: 0
Memory Usage: 30.15 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the hash set is significantly more memory-intensive compared to the Bloom filter (&lt;strong&gt;30.15 MB&lt;/strong&gt; vs. &lt;strong&gt;1.14 MB&lt;/strong&gt;). However, it does not have any false positives and is faster in terms of insertion and querying times. But, imagine a scenario where the blacklist is much larger, and the memory usage becomes a critical factor. This is where Bloom filters shine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory Efficiency&lt;/strong&gt;: Bloom filters use a fixed amount of space regardless of the number of items inserted, making them ideal for applications with limited memory resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: As the size of the data set grows, the memory usage of a hash set grows linearly, whereas a Bloom filter's memory usage remains constant. This makes Bloom filters suitable for very large data sets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Latency&lt;/strong&gt;: By storing the Bloom filter locally, we can quickly determine if a URL might be malicious without frequent network calls, reducing latency and improving user experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pros and Cons of Bloom Filters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Space Efficiency&lt;/strong&gt;: Bloom filters use minimal space compared to other data structures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast Set Membership Tests&lt;/strong&gt;: Bloom filters offer constant-time set membership tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: The memory usage of a Bloom filter remains constant regardless of the number of elements inserted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced I/O Operations&lt;/strong&gt;: Bloom filters can reduce disk reads and network calls by quickly filtering out non-existent elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;False Positives&lt;/strong&gt;: Bloom filters can produce false positives, which may not be acceptable in certain applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimal Parameters&lt;/strong&gt;: Choosing the optimal number of hash functions and bit array size is crucial for minimizing false positives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited Applications&lt;/strong&gt;: Bloom filters are best suited for scenarios where false positives are acceptable and space efficiency is critical.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Case Studies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Case Study: Using Bloom Filters in Google Bigtable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Google Bigtable, a distributed storage system for managing structured data, uses Bloom filters to reduce disk lookups for non-existent rows or columns. By using Bloom filters, Bigtable can quickly determine if a row or column is absent without accessing the disk, thereby improving read performance significantly. This application of Bloom filters showcases their efficiency in handling large-scale data storage and retrieval systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case Study: Akamai's Content Delivery Network (CDN)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Akamai, one of the largest CDNs in the world, uses Bloom filters to quickly determine if content is cached on their edge servers. By using Bloom filters, Akamai can minimize the number of cache misses and reduce the latency of serving content to users. This helps in delivering content more efficiently and improves the overall performance of the CDN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case Study: Medium Duplicate Story Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Medium, a popular online publishing platform, uses Bloom filters to detect duplicate stories. When a user submits a new story, Medium checks if the story is a duplicate by querying a Bloom filter that stores the hashes of previously submitted stories. This helps in identifying and preventing the publication of duplicate content, ensuring a better user experience for readers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case Study: Bitcoin's SPV Nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Bitcoin, Simplified Payment Verification (SPV) nodes use Bloom filters to track transactions relevant to them without downloading the entire blockchain. By using Bloom filters, SPV nodes can operate more efficiently with limited resources, making it feasible for lightweight clients to participate in the Bitcoin network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Bloom filters are a prime example of how probabilistic data structures can offer powerful solutions to space and time efficiency challenges. By understanding and implementing Bloom filters, you can enhance the performance of your applications in scenarios where quick set membership tests are critical. Despite their simplicity, Bloom filters have found their way into various sophisticated systems and continue to be a valuable tool in a programmer's toolkit.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;- &lt;a href="https://tara-annison.medium.com/bloom-filters-and-spv-nodes-within-the-bitcoin-blockchain-66c36ea673f2" rel="noopener noreferrer"&gt;Bloom Filters and SPV nodes within the bitcoin blockchain&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://en.wikipedia.org/wiki/Bloom_filter" rel="noopener noreferrer"&gt;Bloom Filter Wikipedia Page&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://cloud.google.com/blog/products/databases/cloud-bigtable-improves-single-row-read-throughput-by-up-to-50-percent/" rel="noopener noreferrer"&gt;Cloud Bigtable under the hood: How we improved single-row read throughput by 20-50%&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://courses.cs.washington.edu/courses/cse312/22wi/files/student_drive/9.4.pdf" rel="noopener noreferrer"&gt;University of Washington Lecture Slides on Bloom Filter Applications&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://www.geeksforgeeks.org/bloom-filters-introduction-and-python-implementation/" rel="noopener noreferrer"&gt;Bloom Filters – Introduction and Implementation&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://towardsdatascience.com/system-design-bloom-filter-a2e19dcd4810" rel="noopener noreferrer"&gt;System Design: Bloom Filter&lt;/a&gt; &lt;br&gt;
- &lt;a href="https://www.enjoyalgorithms.com/blog/bloom-filter" rel="noopener noreferrer"&gt;Bloom Filter Data Structure: Implementation and Application&lt;/a&gt;&lt;/p&gt;

</description>
      <category>theory</category>
      <category>datascience</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>The Rewarding (Sometimes Painful) Process of Creating a Portfolio Website</title>
      <dc:creator>Micah Kepe</dc:creator>
      <pubDate>Tue, 14 May 2024 03:12:44 +0000</pubDate>
      <link>https://dev.to/micahkepe/the-rewarding-sometimes-painful-process-of-creating-a-portfolio-website-5di1</link>
      <guid>https://dev.to/micahkepe/the-rewarding-sometimes-painful-process-of-creating-a-portfolio-website-5di1</guid>
      <description>&lt;p&gt;Hello, DEV Community! 👋&lt;/p&gt;

&lt;p&gt;Nearly a year ago on June 8th, 2023, I made the first commit for the source code for my website. Starting this project was kind of an accident— setting up a GitHub Pages site was exercise that was mentioned in passing in an online course I was taking so I did it without giving much thought to it. I'd never done web development before that point, but as soon as I saw that first extremely basic website go live I was hooked on seeing how far I could take the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;I did some searching online at other portfolio sites to gain inspiration, taking note of features I loved and those I thought were unnecessary, jotting down notes and ideas for my own site.&lt;/p&gt;

&lt;p&gt;Here you can see one of my earliest drafts of the site that I drew roughly in OneNote just to put all my thoughts together of the site I wanted to create:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcf8ujv4rjz6ka3ufajcj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcf8ujv4rjz6ka3ufajcj.jpeg" alt="First Layout Mockup" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Being as this was my first real web development project, a large majority of the early work in the project was actually research instead of coding. I familiarized myself with popular frameworks and explored various design patterns and best practices. I eventually settled on using React and NodeJS because the vast amount of online content on these would mean that I would have plenty of resources to utilize if I ever got stuck.&lt;/p&gt;

&lt;p&gt;As I delved deeper into the world of web development, I realized that creating a portfolio website was not just about showcasing my projects but also about demonstrating my ability to learn and adapt to new technologies. Each line of code I wrote was a testament to my growing skills and understanding of web development concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headaches and Successes
&lt;/h2&gt;

&lt;p&gt;The journey of building my portfolio website was not without its challenges. There were moments of frustration when things didn't work as expected, and I found myself stuck debugging for hours on end.&lt;/p&gt;

&lt;p&gt;The website felt like a hydra sometimes- I'd cut off the head of one problem only for two more problems to spring up elsewhere:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sgp10msqrirlyj583u4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sgp10msqrirlyj583u4.jpeg" alt="Iterative To-Do List for the Site" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, with each challenge I overcame, I grew more confident in my abilities. I learned the importance of breaking down complex problems into smaller, manageable tasks and tackling them one at a time. I also discovered the power of community and reached out for help when needed, whether it was through online forums, developer communities, or seeking guidance from more experienced developers.&lt;/p&gt;

&lt;p&gt;One of the recent milestones in my journey was integrating a blog into my portfolio website. I wanted a platform to share my experiences, insights, and tutorials with the developer community. To achieve this, I delved into the world of static site generators, exploring options like Jekyll, Hugo, and Gatsby. After weighing the pros and cons, I ultimately chose to use Zola, a fast and flexible static site generator written in Rust. Integrating Zola into my existing website architecture posed its own set of challenges, but the learning experience was invaluable, and the satisfaction of publishing my first blog post made it all worthwhile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwv66w04gm5bow5q16pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwv66w04gm5bow5q16pk.png" alt="Setting up my blog with comment sections" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Throughout this journey, I picked up countless valuable lessons- the importance of version control and learning to set up GitHub workflows to streamline my development process to name just a few. I gained a newfound appreciation for the challenges of web development and the hard work that goes into creating seamless user experiences. I also adopted best practices for writing clean, modular, and maintainable code.&lt;/p&gt;

&lt;p&gt;Perhaps the most significant lesson was the importance of just diving in and starting. It's easy to get caught up in the planning phase, striving for perfection before writing a single line of code. But the truth is, the best way to learn and grow as a developer is by building projects, making mistakes, and iterating along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Looking back on this journey, I am amazed at how far I have come. What started as an accidental exercise has turned into a passion for web development and a valuable learning experience. Building my portfolio website has not only allowed me to showcase my projects and skills but has also taught me the importance of perseverance, continuous learning, and embracing challenges as opportunities for growth.&lt;/p&gt;

&lt;p&gt;I invite you to explore my website and provide your feedback. I would love to hear your thoughts on the design, functionality, and overall user experience:&lt;/p&gt;

&lt;p&gt;🌐 Personal Website: &lt;a href="https://micahkepe.com"&gt;https://micahkepe.com&lt;/a&gt;&lt;br&gt;
📝 Blog: &lt;a href="https://micahkepe.com/blog"&gt;https://micahkepe.com/blog&lt;/a&gt;&lt;br&gt;
💻 GitHub: &lt;a href="https://github.com/micahkepe/micahkepe.github.io"&gt;https://github.com/micahkepe/micahkepe.github.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To anyone considering building a personal website, my advice is simple: just start. Don't worry about having everything figured out from the beginning. Embrace the journey, learn as you go, and enjoy the rewarding experience of creating something that showcases your skills and growth as a developer.&lt;/p&gt;

&lt;p&gt;Best,&lt;br&gt;
Micah Kepe&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
      <category>react</category>
      <category>github</category>
    </item>
  </channel>
</rss>
