<?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>Forem: Alex</title>
    <description>The latest articles on Forem by Alex (@okaz).</description>
    <link>https://forem.com/okaz</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%2F1461791%2Fcedaaeeb-98db-448f-9ef3-6e0520517665.jpeg</url>
      <title>Forem: Alex</title>
      <link>https://forem.com/okaz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/okaz"/>
    <language>en</language>
    <item>
      <title>How to start using Vim</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 07 Oct 2024 14:34:38 +0000</pubDate>
      <link>https://forem.com/okaz/how-to-start-using-vim-5265</link>
      <guid>https://forem.com/okaz/how-to-start-using-vim-5265</guid>
      <description>&lt;p&gt;Almost 30 years have passed since the first version of Vim appeared, but it continues to develop and grow its community. Many projects, such as Neovim, MacVim, etc., were inspired by Vim, which can also be integrated into an IDE or code editor, like Webstorm or VS Code.&lt;/p&gt;

&lt;p&gt;I will not compare Vim with other IDEs or code editors because it makes no sense. In return, I will briefly show you the Vim ecosystem. We will look into ways to use it, and you will understand how you can start using it without struggling and fighting with the editor.&lt;/p&gt;

&lt;p&gt;This article is for people who know little about Vim, but it is still useful for experienced users.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.vim.org/" rel="noopener noreferrer"&gt;Vim&lt;/a&gt; and &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Currently, two main varieties exist: Vim and its fork, Neovim. Most plugins extending the editor are available in both, so you can choose whatever you prefer.&lt;/p&gt;

&lt;p&gt;Earlier, an obvious advantage of Neovim was asynchrony, but modern versions of Vim, starting with version 8, support async I/O. I prefer Neovim, mostly because it has a constantly developing community, plugins better support Neovim than Vim, and actually, it looks much better by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to use
&lt;/h2&gt;

&lt;p&gt;Let’s focus on a few ways of using Vim. I will describe the ways I tried myself, and I believe you can find more if you want to.&lt;/p&gt;

&lt;p&gt;The first way of using vim is very simple. You can install it and use it in the terminal, just run &lt;code&gt;vim&lt;/code&gt; or &lt;code&gt;nvim&lt;/code&gt; command to open the editor. In my opinion, it’s not the best way for beginners, and at the start of the Vim journey, it’s better to use it in your favorite code editor or IDE.&lt;/p&gt;

&lt;p&gt;The following approach is to use Vim with &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VsCode&lt;/a&gt;. If you use it, just install the &lt;a href="https://marketplace.visualstudio.com/items?itemName=vscodevim.vim" rel="noopener noreferrer"&gt;Vim plugin&lt;/a&gt;. The &lt;a href="https://github.com/easymotion/vim-easymotion" rel="noopener noreferrer"&gt;easymotion&lt;/a&gt; plugin will be automatically installed to make you happy. For me, it’s the most important Vim plugin, which significantly increases your coding speed.&lt;/p&gt;

&lt;p&gt;You can also integrate Vim with &lt;a href="https://www.jetbrains.com/" rel="noopener noreferrer"&gt;JetBrains IDEs&lt;/a&gt; using 2 plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://plugins.jetbrains.com/plugin/164-ideavim/" rel="noopener noreferrer"&gt;IdeaVim&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://plugins.jetbrains.com/plugin/7086-acejump/" rel="noopener noreferrer"&gt;AceJump&lt;/a&gt; — it’s easymotion implementation for JetBrains;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://spacevim.org/" rel="noopener noreferrer"&gt;SpaceVim&lt;/a&gt; is a ready—to—use configuration that also provides an interface for configuring the editor and installing plugins. A similar project, &lt;a href="https://www.spacemacs.org/" rel="noopener noreferrer"&gt;Spacemacs&lt;/a&gt;, exists on the Internet, which they were inspired by.&lt;/p&gt;

&lt;p&gt;It’s a good solution for people who want to try using an editor in the terminal but are too busy to configure Vim from scratch.&lt;/p&gt;

&lt;p&gt;If you want to fully immerse yourself in Vim, you can try the &lt;a href="https://chromewebstore.google.com/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?pli=1" rel="noopener noreferrer"&gt;Vimium&lt;/a&gt; extension. With its help, you can use the browser through Vim.&lt;br&gt;
I only tried the extension for Chrome, but there is Vimium for other browsers.&lt;br&gt;
It’s not the most helpful thing, but it’s worth checking out, and maybe you’ll like it. I didn’t like it personally, but I hope it will be helpful for you.&lt;/p&gt;

&lt;p&gt;The most convenient option for a beginner is to integrate Vim and Easymotion into your current editor or IDE, which will be much more convenient than Vim in the terminal.&lt;br&gt;
However, it is unlikely that you will be able to use Vim at work immediately, so it is better to enable it only when you want to learn how to use it and integrate it into your daily work step by step.&lt;/p&gt;

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

&lt;p&gt;To start working with the editor, you should first learn to navigate and learn Vim modes; there should be no difficulties here. After that, you can try writing simple functions and expressions in your favorite programming language just to get used to it.&lt;/p&gt;

&lt;p&gt;Then, you can move on to mastering combinations and commands. The most effective way is to learn a few each day. I mean, try them hands-on and use them later. There is much information about this, so I don’t see the point of stopping here.&lt;/p&gt;

&lt;p&gt;I will separately emphasize the importance of touch typing. Without it, it is impossible to work fully and comfortably with Vim.&lt;/p&gt;

&lt;p&gt;Learning touch typing is not a very pleasant activity and takes quite a lot of time. But if you devote 20–30 minutes a day to it, then in a month, you will be able to type blindly, albeit slowly and with errors.&lt;/p&gt;

&lt;p&gt;First, remember the keys’ location and learn to press them without looking at the keyboard. Next, print simple texts. For beginners, the main thing is not speed but quality, so you should ignore the number of characters per minute.&lt;/p&gt;

&lt;p&gt;When you feel comfortable, you can practice speed. I think it is optimal to reach 100–120 characters per minute. Then the excitement starts, and you want to speed up more and more. There is much information about correct finger placement on the internet for those just beginning to learn how to type unthinkingly. I will focus on resources where you can improve your skills:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typing.com" rel="noopener noreferrer"&gt;https://www.typing.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typingclub.com" rel="noopener noreferrer"&gt;https://www.typingclub.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are beneficial sites. Here, you can increase your speed and reduce the number of errors. In principle, you can learn touch typing while getting to know the combinations in Vim, but it will be more difficult.&lt;br&gt;
After all, the keyboard is your work tool, so touch typing is still worth learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;There are many Vim resources on the internet, especially for beginners. One of the best, in my opinion, is vim.fandom.com/wiki/Vim_Tips_Wiki. It is suitable for those familiar with the ecosystem and can at least navigate the editor and use its modes. This site has a lot of material on various editor combinations, commands, and settings. There are also tutorials dedicated to specific aspects of Vim.&lt;/p&gt;

&lt;p&gt;Another good site about the editor is wikibooks.org/wiki/Vim. I haven’t used it much, but it’s also worth checking out.&lt;/p&gt;

&lt;p&gt;Also, catch some interesting Twitter feeds I read:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://x.com/VimLinks" rel="noopener noreferrer"&gt;twitter.com/VimLinks&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://x.com/Neovim" rel="noopener noreferrer"&gt;twitter.com/Neovim&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://x.com/vimtips" rel="noopener noreferrer"&gt;twitter.com/vimtips&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think this information will be enough to understand the editor’s advantages, both separately in the terminal and in connection with popular code editors and IDEs.&lt;br&gt;
I want to emphasize that patience and persistence are key to getting to know Vim (as in learning anything new).&lt;/p&gt;

</description>
      <category>vim</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Two pointers algorithm explained</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 07 Oct 2024 10:39:06 +0000</pubDate>
      <link>https://forem.com/okaz/two-pointers-algorithm-explained-3k0e</link>
      <guid>https://forem.com/okaz/two-pointers-algorithm-explained-3k0e</guid>
      <description>&lt;p&gt;I want to explain a simple and effective technique that you can use in an interview when dealing with Arrays, Strings, Linked Lists, etc. This will also improve your fundamental knowledge about these data structures.&lt;/p&gt;

&lt;p&gt;Let’s start from theory. There are two common use cases of this algorithm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;left/right&lt;/code&gt; The central concept of this algorithm is to have two integer variables that will move from both sides of a string or array. Usually, people call it &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;. The &lt;code&gt;left&lt;/code&gt; will move from the &lt;code&gt;0&lt;/code&gt; index to the &lt;code&gt;length — 1&lt;/code&gt;, and the &lt;code&gt;right&lt;/code&gt; is the opposite.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;slow/fast&lt;/code&gt; Pointers run in the same direction, e.g., from start to end, but one pointer runs faster than another. In this case, people usually call variables &lt;code&gt;slow&lt;/code&gt; and &lt;code&gt;fast&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algorithms are elementary, and the best way to understand them is to look into some examples.&lt;/p&gt;

&lt;p&gt;First, let’s look at a case with left and right pointers. Here is an elementary example of a problem we can solve using this algorithm. The goal is clear: we want to find a pair whose sum will equal a given number.&lt;br&gt;
The brute force approach will create nested loops, but there’s a low chance of passing the interview using it.&lt;br&gt;
A better approach would be to use the &lt;code&gt;two pointers&lt;/code&gt; algorithm and find it in one loop to have &lt;code&gt;O(n)&lt;/code&gt; complexity instead of &lt;code&gt;O(n²)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findPair&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                 &lt;span class="c1"&gt;// Start with two pointers left from start, right, from the end&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// when pointers meet, finish loop&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;  &lt;span class="c1"&gt;// Return the pair if we find the target sum&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Move left pointer to the right if sum is less than target&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Move right pointer to the left if sum is greater than target&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Return null if no such pair exists&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;findPair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: [2, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s switch to an approach where pointers have different speeds. It’s a frequent problem which you can meet an interview. You need to find the middle of the given Linked List.&lt;br&gt;
The brute force approach is not as bad as the previous example, but the interviewer expects a better one.&lt;br&gt;
With &lt;code&gt;two pointers&lt;/code&gt; algorithm, you will solve this problem with &lt;code&gt;O(n)&lt;/code&gt; complexity, whereas the brute force approach will take &lt;code&gt;O(2n)&lt;/code&gt; if you use two sequential loops.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findMiddle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;fast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Move slow pointer one step&lt;/span&gt;
        &lt;span class="nx"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Move fast pointer two steps&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Slow pointer will be at the middle&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a linked list 1 -&amp;gt; 2 -&amp;gt; 3 -&amp;gt; 4 -&amp;gt; 5&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;node2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;node3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;node4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;node5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;node2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;node3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;node4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;findMiddle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 3 (middle node)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>algorithms</category>
      <category>webdev</category>
      <category>interview</category>
    </item>
    <item>
      <title>Why it is worth passing HashiCorp Certified: Terraform Associate</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 07 Oct 2024 09:20:27 +0000</pubDate>
      <link>https://forem.com/okaz/why-it-is-worth-passing-hashicorp-certified-terraform-associate-3fcb</link>
      <guid>https://forem.com/okaz/why-it-is-worth-passing-hashicorp-certified-terraform-associate-3fcb</guid>
      <description>&lt;p&gt;In this article, I will briefly describe certification and the process and explain the advantages of passing it.&lt;/p&gt;

&lt;p&gt;Firstly, let’s talk about the exam process. In my case, I registered for the exam and took two weeks to prepare because I had worked with Terraform before. After reading the &lt;a href="https://developer.hashicorp.com/certifications/infrastructure-automation" rel="noopener noreferrer"&gt;exam details&lt;/a&gt;, I understood it would be enough. Then, I started preparation and spent approximately one hour per working day preparing for the exam, reading the &lt;a href="https://developer.hashicorp.com/terraform/tutorials/certification-003/associate-study-003?ajs_aid=a288f4ed-e4f8-4427-a04e-4f9233f608bf&amp;amp;product_intent=terraform" rel="noopener noreferrer"&gt;preparation guide&lt;/a&gt;, and creating a small pet project where I tested unfamiliar features.&lt;/p&gt;

&lt;p&gt;In my opinion, you don’t need to buy courses for this exam. It’s pretty straightforward and almost missing tricky questions where you should understand how it works under the hood. It’s better to have practice on small pet project to remember all the necessary information from the preparation guide.&lt;/p&gt;

&lt;p&gt;On an exam day, you must follow the proctor’s instructions about preparing for the workplace. They are strict, and my recommendation is to remove everything from the table, close doors and windows, and remove the watch and other jewelry, not to spend time discussing it with the proctor. And, of course, don’t forget to prepare your ID.&lt;/p&gt;

&lt;p&gt;You can ask me why passing this certification came to my mind. I’ve already passed a few IT certifications and can say it’s helpful for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When preparing, you will read about corner cases or things you are not using frequently and understand the whole system&lt;br&gt;
You will recall many Terraform features, methods, and approaches that you can apply to your projects;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you try to bring Terraform into a new project or move existing infrastructure to IaC, a certificate will be a source of truth you have experience with this;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will help in the interview, mainly if the company uses Terraform as an IaC solution. Also, the interviewer will most likely skip simple questions, and we will talk about deeper topics in Terraform or IaC in general. It will help you sell your skills better;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Summarizing the above, I think it’s a good investment for your future. It costs about 70$ but gives you many more opportunities.&lt;/p&gt;

&lt;p&gt;Also, here, I will leave sources where you can prepare for the certification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.hashicorp.com/certifications/infrastructure-automation" rel="noopener noreferrer"&gt;Terraform exam page&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.hashicorp.com/terraform/tutorials/certification-003/associate-study-003?ajs_aid=a288f4ed-e4f8-4427-a04e-4f9233f608bf&amp;amp;product_intent=terraform" rel="noopener noreferrer"&gt;Preparation guide&lt;/a&gt;;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>webdev</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>The main steps I follow when kicking off Node.js projects</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 07 Oct 2024 07:28:08 +0000</pubDate>
      <link>https://forem.com/okaz/the-main-steps-i-follow-when-kicking-off-nodejs-projects-1929</link>
      <guid>https://forem.com/okaz/the-main-steps-i-follow-when-kicking-off-nodejs-projects-1929</guid>
      <description>&lt;p&gt;In this article, I want to emphasize some steps I follow when developing Node.js applications. These steps help me deliver reliable apps that cover business needs and are flexible and scalable for long-term growth.&lt;/p&gt;

&lt;p&gt;Before starting with approaches and technologies that can solve problems, you should understand which issues you will solve. That’s why the essential thing you should be thinking about is the business context.&lt;br&gt;
You can’t predict how the project will grow after production and what the business will need later. What you can do is discuss what the company needs for the MVP and develop the project in a scalable manner to prepare for later changes and migrations.&lt;/p&gt;

&lt;p&gt;After you have concepts and goals for the MVP, let’s move down to the engineering level and examine approaches and technologies that can help ensure the application's scalability and reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Framework
&lt;/h2&gt;

&lt;p&gt;It’s better to start by choosing the architecture you will implement — monolith, serverless, or microservices. There’s the most common architectural approach for now, but you are not limited here.&lt;br&gt;
You can choose a framework based on the architecture. Be careful here because many frameworks exist in the Node.js ecosystem.&lt;br&gt;
My choices are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt; is excellent for small projects or prototypes, which will be replaced later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nestjs.com/" rel="noopener noreferrer"&gt;Nest.js&lt;/a&gt; covers several architectures, which is a default framework I consider when deciding what to use. It’s excellent for the monolith, which will be divided into domains and later transformed into separate microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://moleculer.services/index.html" rel="noopener noreferrer"&gt;Moleculer&lt;/a&gt; will be good if you consider microservices. Still, I’m not a big fan of creating microservices when the project starts due to the complexity of the infrastructure and overall development processes. It’s an excellent framework for building microservices around your monolith or migrating from monolith to MS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;. Yes, I also consider it when deciding what I should use. It’s perfect if you are the only engineer who will work on the project or if all engineers are full-stack developers. Along with Vercel, you will have many benefits and be able to move quickly. However, later, you will probably need to migrate the backend to a separate codebase due to complexity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.serverless.com/" rel="noopener noreferrer"&gt;Serverless&lt;/a&gt; is fantastic and probably the only solution for handling serverless architecture. It’s incredible for prototyping or small APIs. Still, I prefer to use it along with monolith or MS architectures as additional services or to handle narrow application parts where serverless is suitable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Typescript
&lt;/h2&gt;

&lt;p&gt;It’s suitable for almost every project and architecture. However, I don’t want to stop here because different articles have extensively described its benefits and drawbacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data storage
&lt;/h2&gt;

&lt;p&gt;Of course, you must choose SQL or NoSQL databases based on your business needs, or maybe you need both types of storage. I frequently select from several databases I worked on and have extensive experience with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;My default choice is &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;. It’s perfect relational storage with one of the best optimizers. It can cover most of your needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Frequently, I consider &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;, especially the serverless version. It’s a robust database that benefits from the relational model and is a powerful NoSQL database with many features that most storages don’t provide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you need a powerful NoSQL solution without relational benefits, consider &lt;a href="https://aws.amazon.com/dynamodb/" rel="noopener noreferrer"&gt;DynamoDB&lt;/a&gt;. I also use it frequently, but mostly to handle narrow parts of projects. Be careful with this database because it has a special design you must learn before use. Don’t be like people who create many tables and try to use them as MongoDB or even as relational DB. In this case, you will have big problems when the product grows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, I want to mention non-persistent storages like &lt;a href="https://www.elastic.co/elasticsearch" rel="noopener noreferrer"&gt;ElasticSearch&lt;/a&gt; and &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt;, which I frequently use. ElasticSearch is not good when the project starts, but you can take it into account and use it later when you need to handle complex indexes and searches. Redis or another memory database is friendly and easy to implement. We frequently need a cache even at the beginning of the project, so it’s nice to have it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data access layer
&lt;/h2&gt;

&lt;p&gt;Here, I use different approaches depending on the product side. I like starting with ORM and migrating to query builder or raw SQL in narrow parts. For NoSQL databases, I wouldn’t say I like ODM’s and prefer using drivers. For example, I don’t particularly appreciate using Mongoose and choose Node.js driver instead of this. I think it’s more flexible and simple than ODM, and it doesn’t require you to use the relational model.&lt;/p&gt;

&lt;p&gt;For relational databases, there are many different libraries you can use here, but if you use an SQL database, you can consider &lt;a href="https://typeorm.io/" rel="noopener noreferrer"&gt;TypeORM&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development workflow
&lt;/h2&gt;

&lt;p&gt;The last thing I want to mention is the development workflow. I like to keep it as simple as possible and use easy-to-implement tools to help automate workflows, moving to more flexible and complex solutions if needed. Here are my recommendations for tools you can consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;Github actions&lt;/a&gt;. It’s an excellent CI/CD tool you can configure quickly and easily.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.github.com/en/code-security/getting-started/dependabot-quickstart-guide" rel="noopener noreferrer"&gt;Dependabot&lt;/a&gt; is a fantastic tool for keeping packages in the latest versions and searching for vulnerabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt;. I use it to manage infrastructure. It simplifies many things if at least a few people work on a project. As the project grows, it becomes massive, and maybe for better state management, you will need tools like &lt;a href="https://terragrunt.gruntwork.io/" rel="noopener noreferrer"&gt;Terragrunt&lt;/a&gt; to keep infrastructure-related code simple. If you use AWS as a cloud provider, you can also use &lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;AWS CDK&lt;/a&gt;. It’s a nice tool with Typescript support, but it’s available only for AWS, and if you need something from a different cloud infrastructure, the code will be much more complex than Terraform. That’s why I prefer the Terraform even for AWS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>database</category>
    </item>
  </channel>
</rss>
