<?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: Joonhyeok Ahn (Joon)</title>
    <description>The latest articles on Forem by Joonhyeok Ahn (Joon) (@bitethecode).</description>
    <link>https://forem.com/bitethecode</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%2F960521%2F5fc84b74-091b-46e9-bc23-da14cea343c6.jpeg</url>
      <title>Forem: Joonhyeok Ahn (Joon)</title>
      <link>https://forem.com/bitethecode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bitethecode"/>
    <language>en</language>
    <item>
      <title>How not to create another bug while fixing one</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Fri, 14 Apr 2023 20:57:26 +0000</pubDate>
      <link>https://forem.com/bitethecode/how-not-to-create-another-bug-while-fixing-one-4nio</link>
      <guid>https://forem.com/bitethecode/how-not-to-create-another-bug-while-fixing-one-4nio</guid>
      <description>&lt;p&gt;Many developers make mistakes of making more bugs while trying to fix a bug. People will trust you more if you don't produce these unnecessary outcomes. &lt;/p&gt;

&lt;p&gt;Here are 5 tips that I've learned over time &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Understand the root cause of the bug: Before you start fixing the bug, make sure you understand the root cause of the problem. This will help you to identify potential side effects of the fix. Any reports, logs, or system dashboard can be useful information. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write test cases: Before fixing the bug, write test cases that cover the problem. These test cases should be able to reproduce the bug and should also cover any related scenarios. After you have fixed the bug, run these test cases to verify that the bug has been fixed and that there are no new issues. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Isolate changes: When fixing a bug, try to isolate the changes to the smallest possible area of code. This will help you to identify any potential issues that may arise from the changes you make. And if you are not sure what side effects your changes can make, try to communicate with other members first..! &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review your code: Have someone else review your code before you merge it into the main codebase. A fresh set of eyes may identify issues that you missed. Even if you already covered the automated tests, running a quick manual test will never hurt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor: After you have fixed the bug, monitor the application for any regressions. This involves checking that the fix did not introduce new issues. Again, any reports, logs, or system dashboard can be useful. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was able to produce less bugs after I started applying these tactics to the daily workflow. So try these and become more reliable dev in your team! &lt;/p&gt;

&lt;p&gt;If you like this content, please follow &lt;a href="https://bitethecode.substack.com"&gt;https://bitethecode.substack.com&lt;/a&gt; and &lt;a href="https://github.com/bitethecode"&gt;https://github.com/bitethecode&lt;/a&gt;. I will try to share what I've learned with y'all! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding of context in Go</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Sun, 12 Mar 2023 19:50:54 +0000</pubDate>
      <link>https://forem.com/bitethecode/understanding-of-context-in-go-547c</link>
      <guid>https://forem.com/bitethecode/understanding-of-context-in-go-547c</guid>
      <description>&lt;p&gt;Context is a standard interface allowing you to carry request-scoped values, cancelation signals, and deadlines across API boundaries and between processes. The concept seems straightforward, but it wasn't obvious when I tried applying it to the codebase. After experimenting, I’m sharing what I learned about the context in Go today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Request scoped data
&lt;/h3&gt;

&lt;p&gt;With context, you can pass around &lt;strong&gt;request scoped data&lt;/strong&gt; such as body, headers, or params to downstream. For example, context can contain auth token and this can be passed to middleware or controller for further usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"auth_token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"auth_token"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// prints "token"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add key value pair to context with &lt;code&gt;WithValue&lt;/code&gt; function. When we pass down this derived context, any context from the derived one can see this value. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cancellation
&lt;/h3&gt;

&lt;p&gt;This function returns a derived context from the context passed. A new &lt;code&gt;Done&lt;/code&gt; channel is added, which is closed when the cancel function is invoked or the parent context Done channel is closed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The general rule is only the function that creates derived context should call the cancel function to avoid any unexpected outcomes. Also, always call cancel to release the children's resources held by the parent context. Otherwise, it can lead to a possible memory leak. &lt;/p&gt;

&lt;h3&gt;
  
  
  Timeout/Deadlines
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CancelFunc&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="n"&gt;WithDeadline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, timeout and deadlines serve to avoid holding resources for a while. When timeout exceeds or context is canceled, the Done channel will be closed. If that happens, &lt;code&gt;ctx.Err&lt;/code&gt; will not be nil. So you can find the error cause by a switch statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create context?
&lt;/h2&gt;

&lt;p&gt;There are a few ways to create context. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;context.Background()&lt;/code&gt; this will return the empty context. Most times you can use this as a parent context that will be passed down. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;context.TODO()&lt;/code&gt; this will also return the empty context. Yet, you can use it as a placeholder when you are not sure and want to defer decision. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;r.Context()&lt;/code&gt; this will return the request's context. I use it for most cases since I'm handling API heavily. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is context tree?
&lt;/h2&gt;

&lt;p&gt;In Go, we usually use derived context. The typical workflow is it starts from the parent context, a new context is derived with added additional information, and is passed down to the next layer. So, essentially it makes a context tree. This can be beneficial as you can cancel all the context at once.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bM01Z-uH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1ktzoy7zo44dplqsznx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bM01Z-uH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1ktzoy7zo44dplqsznx.png" alt="Image description" width="880" height="853"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply context cancel
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// simulate a process that takes 4 second to complete&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeadlineExceeded&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"context timeout exceeded"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Canceled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"context cancelled by force. whole process is complete"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain the code snippet above. The main program creates a new context with a cancelation signal that will be triggered after 3 seconds. Then it starts a long-running go routine that listens for the context to be canceled. As the go routine takes more than time out configured, the go routine will be canceled. As the main program is listening to the context channel, it will print out “context timeout exceeded" after the context is canceled.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If background workers share context for context in the HTTP cycle, this can be canceled when the context from the request is canceled. If you don't want this, you should create a brand new context for background processing using &lt;code&gt;context.Background()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pass request-scoped data only using context. Other data should be passed via function arguments.&lt;/li&gt;
&lt;li&gt;Be careful of goroutine leaks&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Context library is so nice and simple, we have to use it with caution as it can result in unexpected behavior in the codebase. I wish you understand better the context after reading this. &lt;/p&gt;

&lt;p&gt;If you like this follow &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt; and &lt;a href="https://github.com/bitethecode"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stand out among developers with customized Github profile</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Fri, 24 Feb 2023 17:09:26 +0000</pubDate>
      <link>https://forem.com/bitethecode/stand-out-among-developers-with-customized-github-profile-1237</link>
      <guid>https://forem.com/bitethecode/stand-out-among-developers-with-customized-github-profile-1237</guid>
      <description>&lt;h2&gt;
  
  
  Why Github Profile?
&lt;/h2&gt;

&lt;p&gt;Github allows developers to customize their profiles. People can see your profile when they access to "&lt;a href="http://github.com/your-user-name" rel="noopener noreferrer"&gt;github.com/your-user-name&lt;/a&gt;". With this, you can share who you are and what you do as a developer. One big benefit is you can save your time building a portfolio site from a scratch. It's also a perfect place to showcase what you do since it stores all your Git history.&lt;/p&gt;

&lt;p&gt;So, let's customize your Github profile and advertise yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;This is my Github profile. I tried to keep it simple and sweet but you can make yours however you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2v9b0fqsb7itbz0368w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2v9b0fqsb7itbz0368w.png" alt=" " width="632" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to start it?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in to Github&lt;/li&gt;
&lt;li&gt;Create a new repository&lt;/li&gt;
&lt;li&gt;Name a repository name with your &lt;strong&gt;username&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Make sure to set &lt;strong&gt;public&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjew07yncnecne7icwlkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjew07yncnecne7icwlkm.png" alt=" " width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, you will have a newly created repository with &lt;a href="http://readme.md/" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;. You can customize your profile by modifying this file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is README.md?
&lt;/h2&gt;

&lt;p&gt;The readme is based on markdown. With markdown, you can add your flavor to the plain text. For example, you can make a certain sentence bold. Or you can add tables to your docs.&lt;/p&gt;

&lt;p&gt;If you never used markdown before, start with &lt;a href="https://www.markdownguide.org/cheat-sheet/" rel="noopener noreferrer"&gt;this&lt;/a&gt;. As we can use markdown in other places, I recommend spending time playing with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to put in?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The general rule
&lt;/h3&gt;

&lt;p&gt;I'd like to think Github profile as a resume. If you put too many highlights, people will get distracted by your messy resume and lose interest. So, keep in mind that simplicity is the best.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who you are
&lt;/h3&gt;

&lt;p&gt;First of all, tell people who you are. Your name, your job title, or your interest. Tell people who you are.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you do
&lt;/h3&gt;

&lt;p&gt;Next, let people know what you are working on.&lt;/p&gt;

&lt;p&gt;If you have a job,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what is your job title&lt;/li&gt;
&lt;li&gt;what is your current tech stack&lt;/li&gt;
&lt;li&gt;what is your role in your current position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have a job,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what do you want to be&lt;/li&gt;
&lt;li&gt;what do you study or prepare now&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may capture the opportunities by sharing this information when future employers look through your Github profile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlights
&lt;/h3&gt;

&lt;p&gt;Not everything you do is equally significant to the audience. Instead of putting A-Z, make a few bullet points. What is your highlights? What are the projects that you are proud of the most? Remember, keep it simple and sweet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add flavors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Utilizing the packages
&lt;/h3&gt;

&lt;p&gt;There are free packages you can use to make your profile more visually enjoyable. I will introduce a few I use for mine.&lt;/p&gt;

&lt;p&gt;One popular is Github Streaks. It provides a visual of your total contributions and streaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2lm5ruo1u37sdqpoonn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2lm5ruo1u37sdqpoonn.png" alt=" " width="521" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another popular one is Github Stats. It provides a visual of your Git history.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13yi3tf3zcnslm6utprn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13yi3tf3zcnslm6utprn.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These packages are easy to set up. If you access to the sites, you can simply copy and paste code. And replace the username with yours then magic will happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Github Actions
&lt;/h3&gt;

&lt;p&gt;Github actions is CI/CD platform that allows you to automate your workflow. You can make your profile more delightful with Github actions.&lt;/p&gt;

&lt;p&gt;To use Github actions,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your Github profile repository and click the &lt;strong&gt;Actions&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt;Click the new workflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxoytoay2quc47x65uxb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxoytoay2quc47x65uxb.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure Yaml to your own needs. A few notes about configuration.

&lt;ol&gt;
&lt;li&gt;You can change the workflow name as you want.&lt;/li&gt;
&lt;li&gt;You can schedule this workflow to make it run automatically.&lt;/li&gt;
&lt;li&gt;You can use solutions that other developers already built.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxanxp6zf29in2t943au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxanxp6zf29in2t943au.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the workflow I'm using to fetch what I've written on my blog.&lt;/p&gt;

&lt;p&gt;You can find more Github actions in &lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Today I covered Github profile. It can be daunting to set up the profile at once. So start with the bare minimum and update as you go. As every developer is using Github for their development work, having the right profile can bring you unexpected opportunities. You can use mine if you want to have a kick starter &lt;a href="https://github.com/bitethecode/bitethecode" rel="noopener noreferrer"&gt;Github Profile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you like this, follow &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt; and &lt;a href="//github.com/bitethecode"&gt;Github&lt;/a&gt; for more useful content..!&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gautamkrishnar/blog-post-workflow" rel="noopener noreferrer"&gt;Blogpost RSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DenverCoder1/github-readme-streak-stats" rel="noopener noreferrer"&gt;Github Streaks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;Github Stats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gautamkrishnar/blog-post-workflow" rel="noopener noreferrer"&gt;Blog Rss Github Actions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Right Backend Roadmap</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Mon, 06 Feb 2023 21:29:43 +0000</pubDate>
      <link>https://forem.com/bitethecode/the-right-backend-roadmap-18f7</link>
      <guid>https://forem.com/bitethecode/the-right-backend-roadmap-18f7</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;When I started working as a software engineer a few years ago, I wasn't clear on what I should learn to be better at my job. When I tried to search on the internet, I was even more confused. Every day, trends changed. And so many people put emphasis on their own roadmaps to draw attention. I was able to discern what is important over time. Yet, I wished there were people and resources that can point in the right direction. &lt;/p&gt;

&lt;h2&gt;
  
  
  So, what matters?
&lt;/h2&gt;

&lt;p&gt;We cannot learn everything at once with limited time and energy. We should focus our energy on what matters. I will cover the most important topics that every backend developer should know.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basics of programming languages
&lt;/h2&gt;

&lt;p&gt;Pick up one language and be decent about it. Here are a few options for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Java&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Php&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Javascript&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please, don't judge which language is the best this year. People always have their own preferences and there is a trend. These will change. Yet, you will always be on top of the game if you have a fundamental understanding.&lt;/p&gt;

&lt;p&gt;So, learn about&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Variables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Control flows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loops &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data Types e.g) array, map&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Class/Interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Errors&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, put the time to understand Object Oriented Programming. OOP makes software development easier with modularity, reusability, etc.  &lt;/p&gt;

&lt;p&gt;If you master these, you should be able to easily pick up another language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frameworks
&lt;/h2&gt;

&lt;p&gt;Most dev teams use frameworks. Frameworks provide common functionalities and boilerplate code. So, we can save our time and energy from mundane tasks. Many programming languages have their popular frameworks. Pick one and learn about&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Errors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MVC (model, view, and controller)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Workers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From there, you can take in more when needed. &lt;/p&gt;

&lt;h2&gt;
  
  
  APIs
&lt;/h2&gt;

&lt;p&gt;APIs are the fundamental blocks in building software. The benefit of APIs is services can communicate without knowing how it's implemented. Let's say we are building restaurant software. API consumers ask for information about menus. API returns the data without letting consumers know how it's working behind the curtain. &lt;/p&gt;

&lt;p&gt;You can build APIs via RESTful. Or graph. Take one and learn it. &lt;/p&gt;

&lt;p&gt;Make sure you understand these first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CRUD (create, read, update, and delete)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authenticate and authorize &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Version &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request and response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Status code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Database
&lt;/h2&gt;

&lt;p&gt;Any backend services use the database to store records. People can choose either RDMS (Relational Database Management System) or NoSQL. It's your choice. Yet, it's beneficial to understand how SQL is working first.&lt;/p&gt;

&lt;p&gt;Learn about&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to design the database with entities, attributes, and relationships&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types of keys e.g) primary key, foreign key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type of joins e.g) inner join, outer join, etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ACID &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transactions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SQL syntax&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, learn about &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to connect backend services to the database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to use ORM&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to lazy load&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to avoid the N+1 issue&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;I will start with an assumption that we all think testing is important for building software. There are different types of testings &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;manual testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;unit testing &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;e2e testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with unit tests. Unit tests make sure the smallest testable parts are tested for various scenarios. With unit tests, we can&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;catch bugs earlier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;refactor easier. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;reduce code complexity&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, learn about &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;how to write unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TDD&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;integration, e2e, or manual tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Today I covered what you should know as a backend engineer. For sure, there will be more to learn over time, you should have strong pillars first to build a strong house. Your fundamentals will carry you anywhere you go!&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>discuss</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>Which social media are you on?</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Wed, 01 Feb 2023 19:07:49 +0000</pubDate>
      <link>https://forem.com/bitethecode/which-social-media-are-you-on-if</link>
      <guid>https://forem.com/bitethecode/which-social-media-are-you-on-if</guid>
      <description>&lt;p&gt;I used to have Twitter only. &lt;br&gt;
I like Twitter as great minds from different fields share thoughts and be friends, but it's daunting a few times. I felt behind and imposter with the nature of frenetic pace in Twitter. &lt;/p&gt;

&lt;p&gt;Yet, I still want to keep a few social media as I want to to make connections or share what I learn. &lt;/p&gt;

&lt;p&gt;Which social media do you use as a developer?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Docker tutorial - dive into docker-compose</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Mon, 30 Jan 2023 18:48:07 +0000</pubDate>
      <link>https://forem.com/bitethecode/docker-tutorial-dive-into-docker-compose-2l02</link>
      <guid>https://forem.com/bitethecode/docker-tutorial-dive-into-docker-compose-2l02</guid>
      <description>&lt;h1&gt;
  
  
  published
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;What is Yaml?&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.tothe-essential-syntax"&gt;The essential syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Further explanation about services&lt;/li&gt;
&lt;li&gt;Build with compose commands&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Now you should be able to run the Docker container with your image. In reality, there will be more services involved in software development. You might have your core service, database, cache, and more when you are building the backend. We can run Docker containers with the CLI and connect to components, yet it can be tricky. Docker provides a tool &lt;code&gt;Compose&lt;/code&gt; to run multi-containers with ease. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Yaml?
&lt;/h2&gt;

&lt;p&gt;Compose uses the YAML file to configure the multi containers. Yaml is one of the DSLs and is usually used for configuration purposes. &lt;/p&gt;

&lt;h2&gt;
  
  
  The essential syntax
&lt;/h2&gt;

&lt;p&gt;Compose also offers a quite few syntaxes but I will cover only the most used from my own experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  frontend:
    image: awesome/webapp
    ports:
      - "443:8043"
    networks:
      - front-tier
      - back-tier
    configs:
      - httpd-config
    secrets:
      - server-certificate

  backend:
    image: awesome/database
    volumes:
      - db-data:/etc/data
    networks:
      - back-tier

volumes:
  db-data:
    driver: flocker
    driver_opts:
      size: "10GiB"

configs:
  httpd-config:
    external: true

secrets:
  server-certificate:
    external: true

networks:
  # The presence of these objects is enough to define them
  front-tier: {}
  back-tier: {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the official docs, a Compose file must declare the &lt;code&gt;services&lt;/code&gt; top element. Values will be service definitions. And the service contains the configuration that will be applied to each container. There are frontend and backend services in our case. A Compose file can have &lt;code&gt;volumes&lt;/code&gt; as a top element, which serves as a persistent layer. A Compose file can also have &lt;code&gt;networks&lt;/code&gt; as a top element. Any containers belonging to the networks can communicate. For example, frontend and backend services can communicate  via the back-tier network. Configs and secrets are read-only elements for configuration purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further explanation about services
&lt;/h2&gt;

&lt;p&gt;In most cases, &lt;code&gt;services&lt;/code&gt; will be our main interest. Let's deep dive into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web:
    build: .
    image: awesome/web
    ports:
      - "3000:3000"
    networks:
      - front-tier
      - back-tier
    depends_on:
      - db:
          condition: service_healthy
    environment:
      - SERVER_ENVIRONMENT: development
    configs:
      - httpd-config
    secrets:
      - server-certificate
    volumes:
      - db-data:/etc/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;build&lt;/code&gt; specifies the build instruction. &lt;code&gt;.&lt;/code&gt; tells the compose to find the Dockerfile in the current directory. If the build exists, it's okay to omit image declaration. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;image&lt;/code&gt; specifies the image to start the container from. The Compose will try to install the image first if not existed. Then it will run other instructions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ports&lt;/code&gt; specifies the exposed ports. The syntax is &lt;code&gt;HOST[ip:]port:CONTAINER's port&lt;/code&gt;&lt;br&gt;
&lt;code&gt;3000:3000&lt;/code&gt; means to map port 3000 in the machine to port 3000 in the container. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;depends_on&lt;/code&gt; specifies the dependencies in start-up and shutdown. In the above example, Compose will create db. Then it will wait until the db is healthy before creating the web. This can be useful when we have dependencies and services that we have to create in order.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;environment&lt;/code&gt; specifies the variables set in the container. You can also specify the variables with &lt;code&gt;env_file&lt;/code&gt; . If both are present, the environment will take precedence. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;volumes&lt;/code&gt; specifies the instruction on how to mount the volume for persisting data. The syntax is &lt;code&gt;[SOURCE VOLUME:]CONTAINER_PATH&lt;/code&gt;. If the source volume is empty, the compose will create a directory. Then it will mount it as a volume to the target path inside the container. &lt;/p&gt;

&lt;p&gt;From my experience, these specifications have covered the majority of use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build with compose commands
&lt;/h2&gt;

&lt;p&gt;The typical workflow for development will be code, build, test, and push. You can take advantage of the compose to speed up your development process. I see this quite useful when a team onboards newcomers. Compose can save the setup time for new comers when they are not familiar with the system yet, &lt;/p&gt;

&lt;p&gt;Here are a few useful CLI for your disposal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up&lt;/code&gt; create and start containers. If pass the parameter &lt;code&gt;-d&lt;/code&gt;,  you can run them in detached mode.&lt;br&gt;
&lt;code&gt;docker-compose down&lt;/code&gt; stop and remove containers, networks, images, and volumes.&lt;br&gt;
&lt;code&gt;docker-compose stop&lt;/code&gt; stop services without any destructive operations.&lt;br&gt;
&lt;code&gt;docker-compose logs&lt;/code&gt; shows the logs from the containers. &lt;br&gt;
&lt;code&gt;docker-compose exec&lt;/code&gt; executes a command in a running container. &lt;/p&gt;

&lt;p&gt;With these commands, you can manage many containers without hassle.&lt;/p&gt;

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

&lt;p&gt;I covered the concept of docker-compose and useful commands. Try to run multi containers of yours. I will cover useful commands and aliases you can apply to your workflow in the next article.&lt;/p&gt;

&lt;p&gt;If you like this content, follow&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bitethecode" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitethecode.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@the-writer-dev" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html" rel="noopener noreferrer"&gt;https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/compose-file/" rel="noopener noreferrer"&gt;https://docs.docker.com/compose/compose-file/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>crypto</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>offers</category>
    </item>
    <item>
      <title>How to prepare the future as a software engineer</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Fri, 20 Jan 2023 18:40:01 +0000</pubDate>
      <link>https://forem.com/bitethecode/how-to-prepare-the-future-as-a-software-engineer-1jl2</link>
      <guid>https://forem.com/bitethecode/how-to-prepare-the-future-as-a-software-engineer-1jl2</guid>
      <description>&lt;p&gt;There are multiple rounds of massive layoffs in tech. Software engineers were once considered one of the most secure positions, but not anymore. So, what are you supposed to prepare for the uncertain future? The answer is obvious. Make you irreplaceable.&lt;/p&gt;

&lt;p&gt;Here are a few you can do to make yourself more valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Participate in open-source projects
&lt;/h2&gt;

&lt;p&gt;Involving in open-source projects can seem daunting. Yet, it’s fun and beneficial once you start it. The biggest benefit is you can learn about your topic in depth. I was able to learn more about the CI/CD process and logs by contributing to a few backend projects. Plus, you can learn from more experienced engineers via peer review. This expands my understanding of development in general. Last but not least, open-source contributions are proof of your work. This can be your new resume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build your own projects
&lt;/h2&gt;

&lt;p&gt;Working on side projects sounds boring. Yet, we can’t ignore the benefits. I don’t recommend building an Instagram clone. What I recommend is to build what you wish you had. As a software engineer, you may have ideas, but you may have never implemented them. “This sucks”, “How this poor service makes money?”. Fix them, publish them. Your side projects can be your full-time in the future. At least, you will learn way more about engineering than watching Udemy courses. Your project will make you stand out among the crowd.&lt;/p&gt;

&lt;h2&gt;
  
  
  Study data structures and algorithms
&lt;/h2&gt;

&lt;p&gt;I observed a ton of engineers don’t like to work at their current places, yet they stick to it as they are more afraid of technical interviews. Whether you like it or not, tech companies still do a technical round to find the best candidate. I don’t say it’s the best approach to finding great candidates. Yet, it's the price you have to pay for opportunities. For those who want to learn data structures and algorithms, I'm writing everything about tech interviews here → Ace Interview. Star it and use it for your own sake.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
If you are preparing for yourself, you should never worry about your job. Life can be uncertain, yet we can still remain calm if we are willing to.&lt;/p&gt;

&lt;p&gt;If you like this content, follow &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt; or &lt;a href="https://github.com/bitethecode" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Docker tutorial - understanding of Dockerfile</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Mon, 16 Jan 2023 19:28:52 +0000</pubDate>
      <link>https://forem.com/bitethecode/docker-tutorial-understanding-of-dockerfile-2mjb</link>
      <guid>https://forem.com/bitethecode/docker-tutorial-understanding-of-dockerfile-2mjb</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is Dockerfile?&lt;/li&gt;
&lt;li&gt;Why do we need it?&lt;/li&gt;
&lt;li&gt;Essential commands&lt;/li&gt;
&lt;li&gt;Baking an image&lt;/li&gt;
&lt;li&gt;Starting a container&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Dockerfile?
&lt;/h2&gt;

&lt;p&gt;Dockerfile is a text file that contains a set of instructions. If run, we can build an image. Then we can run containers with a built image&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need it?
&lt;/h2&gt;

&lt;p&gt;We can use pre-built images like Postgres. Yet, we have to build images for our core services though. To containerize this, we have to make Dockerfile. Thanks to its simplicity, we can start building our images with a few commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Essential commands
&lt;/h2&gt;

&lt;p&gt;The following commands are the basic ingredients to build an image. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;FROM&lt;/code&gt; tells the base image to start the process. E.g) linux-alpine&lt;br&gt;
&lt;code&gt;RUN&lt;/code&gt; and &lt;code&gt;CMD&lt;/code&gt; tell commands to run. &lt;br&gt;
The difference is &lt;code&gt;RUN&lt;/code&gt; will get executed while building an image. &lt;code&gt;CMD&lt;/code&gt; will get executed by default when we launch the built image.&lt;br&gt;
&lt;code&gt;ADD&lt;/code&gt; copies the files from the source to the destination inside the container.&lt;br&gt;
&lt;code&gt;ENV&lt;/code&gt; sets the environment variables&lt;br&gt;
&lt;code&gt;ARG&lt;/code&gt; variables are only available while building an image.&lt;br&gt;
&lt;code&gt;EXPOSE&lt;/code&gt; tells the Docker container to listen to specific ports.&lt;br&gt;
&lt;code&gt;WORKDIR&lt;/code&gt; sets the working directory for commands like &lt;code&gt;RUN&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Baking an image
&lt;/h2&gt;

&lt;p&gt;Now you understand the basic commands, let's look at the following one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the base image node, it will copy all from /app to /app. Next, it will run yarn install for dependencies. Once it finishes the installation. The process completes. &lt;/p&gt;

&lt;p&gt;Tip: CMD and EXPOSE will get run when starting a container based on this image. &lt;/p&gt;

&lt;p&gt;To build an image, run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t first-try.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will build an image. If you pass &lt;code&gt;.&lt;/code&gt;, Docker will look for Dockerfile in the current directory. After building an image, it will tag the image you pass. In this case, I tag it as a "first-try". &lt;br&gt;
Tip: tag is not required. It's more for a human-readable label.&lt;/p&gt;
&lt;h2&gt;
  
  
  Starting a container
&lt;/h2&gt;

&lt;p&gt;Once we have the Docker image baked, we can run a container. Run,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d first-try
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tip: &lt;code&gt;-d&lt;/code&gt; is the option for detached mode. If you pass this option, Docker will run in the background. &lt;/p&gt;

&lt;p&gt;To see your container's status, run &lt;code&gt;docker ps&lt;/code&gt;. &lt;/p&gt;

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

&lt;p&gt;Now, you should be able to build an image and run containers with your image. What if we need to run more complicated software? What if it has a database or cache? Docker provides a tool &lt;code&gt;docker compose&lt;/code&gt; for running a multi-container codebase. We will look into it in the next article.&lt;/p&gt;

&lt;p&gt;If you like this content, follow &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt; or my &lt;a href="https://github.com/bitethecode" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>How to start off January well</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Tue, 10 Jan 2023 18:48:48 +0000</pubDate>
      <link>https://forem.com/bitethecode/how-to-start-off-january-well-1nlb</link>
      <guid>https://forem.com/bitethecode/how-to-start-off-january-well-1nlb</guid>
      <description>&lt;p&gt;January is the most important month as it can set the tone of your year. If you still don't know how to spend your very first month in 2023, do this!&lt;/p&gt;

&lt;p&gt;Dry yourself&lt;br&gt;
There are fewer social events in January. So use this time not to drink! Keep your brain sharp.&lt;/p&gt;

&lt;p&gt;Use this month to set 1 good habit&lt;br&gt;
Researches say it takes at least 21 days to build a new habit. You have 21 days left. Here are a few good examples.&lt;/p&gt;

&lt;p&gt;Writing 30 minutes&lt;/p&gt;

&lt;p&gt;Studying 30 minutes&lt;/p&gt;

&lt;p&gt;Work out for 30 minutes&lt;/p&gt;

&lt;p&gt;Talk with your beloved ones without digital devices&lt;/p&gt;

&lt;p&gt;Choose one of them and start today. And never break a streak.&lt;/p&gt;

&lt;p&gt;Set up your goals People may say you have too much stuff to do. Wrong. That means people don't have clarity about goals. So spend time to find which ones you really want to achieve this year. Then set up the right priorities.&lt;/p&gt;

&lt;p&gt;That's it! If you like this content follow &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>New Youtube Channel for Every Software Engineers</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Sat, 07 Jan 2023 15:35:08 +0000</pubDate>
      <link>https://forem.com/bitethecode/new-youtube-channel-for-every-software-engineers-1pal</link>
      <guid>https://forem.com/bitethecode/new-youtube-channel-for-every-software-engineers-1pal</guid>
      <description>&lt;p&gt;I decided to start Youtube to share what I learn about software development along with the project &lt;a href="https://github.com/bitethecode/things-I-wish-I-had" rel="noopener noreferrer"&gt;Things I wish I had&lt;/a&gt;.&lt;br&gt;
I will focus on backend development, data structures &amp;amp; algorithms, and open source projects. If you like to see more useful content in depth, start follow &lt;a href="https://www.youtube.com/@the-writer-dev" rel="noopener noreferrer"&gt;https://www.youtube.com/@the-writer-dev&lt;/a&gt;. You will not regret..! Thanks!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Git tutorials - understanding of rebase and merge</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Tue, 03 Jan 2023 16:13:02 +0000</pubDate>
      <link>https://forem.com/bitethecode/git-tutorials-understanding-of-rebase-and-merge-2cg4</link>
      <guid>https://forem.com/bitethecode/git-tutorials-understanding-of-rebase-and-merge-2cg4</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;Why branches start diverging&lt;/li&gt;
&lt;li&gt;Git merge&lt;/li&gt;
&lt;li&gt;Git rebase&lt;/li&gt;
&lt;li&gt;When to use merge or rebase&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In a previous article, I explained how to reconcile merge conflicts. I will explain in depth why we see diverging branches and options to resolve them. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why branches start diverging
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszu4m80dw5febokl7l3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszu4m80dw5febokl7l3e.png" alt="Image description" width="522" height="270"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.atlassian.com/git/tutorials/using-branches/git-merge" rel="noopener noreferrer"&gt;Image by Atlassian&lt;/a&gt;&lt;br&gt;
As shown above, any dev teams protect the master branch. So you have to branch off the master branch and start making changes. In the meantime, others can update the master branch. If those diverging branches were not overlapping the codebase, that's fine. Yet, we will see the changes in the identical parts. Then Git doesn't know which one takes for consolidation. &lt;/p&gt;

&lt;p&gt;So we need to reconcile conflicts before pushing our changes to the prod. &lt;/p&gt;
&lt;h2&gt;
  
  
  Git merge
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9s5o5dj1kgltu7ybvbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9s5o5dj1kgltu7ybvbc.png" alt="Image description" width="537" height="298"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.atlassian.com/git/tutorials/using-branches/git-merge" rel="noopener noreferrer"&gt;Image by Atlassian&lt;/a&gt;&lt;br&gt;
Merging is one way to resolve discords. Merging creates a new commit that combines the history of two branches. So, merging doesn't rewrite Git history. Yet, the Git history can become messy when we bring changes from many branches. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psw2z1cubzboq2axkrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psw2z1cubzboq2axkrx.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;a href="https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge" rel="noopener noreferrer"&gt;Image from Stackoverflow&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  How to merge it?
&lt;/h3&gt;

&lt;p&gt;The idea is simple. Go to the target branch and merge the branch you want to bring changes. If there are no conflicts, merging is successful. If not, you have to resolve the conflicts. To do so, refer to the previous article [[Git - Ch3]]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout dev
git merge master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git rebase
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2gx68khgf4leb7rmp3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi2gx68khgf4leb7rmp3j.png" alt="Image description" width="800" height="366"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.gitlab.com/ee/topics/git/git_rebase.html" rel="noopener noreferrer"&gt;Image by Gitlab&lt;/a&gt;&lt;br&gt;
Rebasing is another way to resolve discords. Unlike merging, rebasing doesn't create a new commit. Instead, it brings commits from the branch you want to incorporate and replay all your commits on top of it. Rebasing is nice as it doesn't create a merge commit. It also guarantees the linear Git history, which is cleaner than merging. &lt;/p&gt;
&lt;h3&gt;
  
  
  How to rebase?
&lt;/h3&gt;

&lt;p&gt;Go to the target branch and rebase the branch. Go to the target branch and rebase the branch you want to bring changes. If there are no conflicts, the rebase is successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout dev
git rebase master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to use merge or rebase
&lt;/h2&gt;

&lt;p&gt;I see the pros and cons of merge/rebase. It has been a debate ever since I started the dev career. The answer is nothing wrong with either approach. It will be beneficial to pick one method and be consistent. So, you can use the following questions to find out which way is better for your team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is your team familiar with rebase?
&lt;/h3&gt;

&lt;p&gt;If not, the answer is obvious. As rebasing will rewrite history, this can be a destructive operation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Is your team big?
&lt;/h3&gt;

&lt;p&gt;If your team size is small, both approaches should work well. If your team size is big, consider rebasing for clean Git history.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are the branch represents grouped information?
&lt;/h3&gt;

&lt;p&gt;If your team uses a branch-per-feature model, merging will be easier to revert as it contains a set of relative commits.&lt;/p&gt;

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

&lt;p&gt;There is no single answer for all situations. So, check your team's context to find which way will be the best. &lt;br&gt;
Next time, I will cover rebase, which can use for other tasks like squeezing commits.&lt;/p&gt;

&lt;p&gt;For more useful content, follow me &lt;a class="mentioned-user" href="https://dev.to/bitethecode"&gt;@bitethecode&lt;/a&gt; or on &lt;a href="https://github.com/bitethecode" rel="noopener noreferrer"&gt;Github&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>graphql</category>
      <category>devops</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What books I read this year</title>
      <dc:creator>Joonhyeok Ahn (Joon)</dc:creator>
      <pubDate>Fri, 23 Dec 2022 18:16:33 +0000</pubDate>
      <link>https://forem.com/bitethecode/what-books-i-read-this-year-ak</link>
      <guid>https://forem.com/bitethecode/what-books-i-read-this-year-ak</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;Lessons from Atomic Habits&lt;/li&gt;
&lt;li&gt;A few more strategies&lt;/li&gt;
&lt;li&gt;List of books I read&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;When I was a kid, I loved reading. I heard from my family that I was holding books even when I ate. Yet, I started losing interest in books over time. I had to study, graduate, and make a living. I made excuses. "I don't have enough time to read!". This year, I happened to read a book called "Atomic Habits" written by James Clear. After I finished reading it, I decided to bring my reading habits back to life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons from Atomic Habits
&lt;/h2&gt;

&lt;p&gt;The author says there are four steps in any habit we do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cue&lt;/li&gt;
&lt;li&gt;craving&lt;/li&gt;
&lt;li&gt;response &lt;/li&gt;
&lt;li&gt;reward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's think about a typical example. You feel bored while waiting for a bus (cue &amp;amp; craving). Then you open SNS and you feel entertained (response &amp;amp; reward). For any habit, we can either make these four patterns work for reinforcing a good habit or stopping a bad one. &lt;/p&gt;

&lt;p&gt;When looking back, I stopped reading not because I didn't have enough time. I stopped as there was more entertaining media - Youtube, Netflix, or SNS. To bring reading to life, I needed to work on two things. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spend less time in entertaining media &lt;/li&gt;
&lt;li&gt;spend more time in reading &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The author gives a few strategies for forming a habit. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make it obvious. &lt;/li&gt;
&lt;li&gt;Make it attractive. &lt;/li&gt;
&lt;li&gt;Make it easy. &lt;/li&gt;
&lt;li&gt;Make it satisfying. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tactics were enough to reduce screen time. First, I removed Youtube, LinkedIn, and other social media from my phone and laptop. Second, I put my phone in different places while I'm working or spending time with family. By making the device boring and inaccessible, I felt I became less attached to it. &lt;/p&gt;

&lt;h2&gt;
  
  
  A few more strategies
&lt;/h2&gt;

&lt;p&gt;While I'm working on less screen time, I need to make a routine for reading. &lt;/p&gt;

&lt;h3&gt;
  
  
  Set up reading time
&lt;/h3&gt;

&lt;p&gt;I felt tired when I tried reading after work. Even when I had time after dinner, I didn't have the mental capacity to read through and take it in. So, I tried reading in the morning. It turned out wonderful. The obvious benefit was that my brain was ready for taking in what books offer after 7 hours of sleep. Another one was the tranquility that morning offers. When I woke up around 5 am, the whole world was silent. I didn't have to see the emails or messages. I only focus on what I'm reading. I slowly became addicted to this positive experience. For these reasons, I kept waking up early in the morning and staying in my den for reading. &lt;/p&gt;

&lt;h3&gt;
  
  
  Paper books are better
&lt;/h3&gt;

&lt;p&gt;I used to read ebooks. You can read books regardless of your location and time. Yet, I noticed the phone is distracting. Alarms and notifications wait for the response. So, I started reading paper books. You have to carry the physical books and it costs more money. Yet, I found a few beautiful points while reading paper books. First, each book uses different textures and fonts. This gives a new experience for each book. Also, I involve more in reading by highlighting lines or scribbling. Lastly, I could remember more than ebooks after reading. &lt;/p&gt;

&lt;h3&gt;
  
  
  Languages don't matter
&lt;/h3&gt;

&lt;p&gt;I thought I should read in English all the time if I wanted to improve my English skills over time. This led me not to read about novels, essays, or short forms as they include more descriptive and poetic expressions. Once I threw that bias about the languages, I could expand categories and read any forms if I'm interested.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fight with biases
&lt;/h3&gt;

&lt;p&gt;I did have biases about books. Here are a few you might be familiar with. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have to finish it once you start&lt;/li&gt;
&lt;li&gt;You have to read in order&lt;/li&gt;
&lt;li&gt;You have to read different categories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These biases made reading unattractive. So, I decided to take different approaches. Instead of obsessing about reading the entire book, I stopped reading when it starts boring or hard to read. I moved on to other books without feeling guilty. I also stopped obsessing about reading in order. I went to the index page and picked up the chapters that hooked my eyes. Finally, I stopped obsessing about reading in variety based on recommendations. Instead, I started reading that interested me. &lt;/p&gt;

&lt;p&gt;I learned that there is no perfect way for reading books. &lt;/p&gt;

&lt;h2&gt;
  
  
  List of books I read
&lt;/h2&gt;

&lt;p&gt;There might be books I missed. Yet.. here is the best I can remember.&lt;/p&gt;

&lt;h3&gt;
  
  
  Books written in English
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Atomic Habits &lt;/li&gt;
&lt;li&gt;Deep Work&lt;/li&gt;
&lt;li&gt;So Good They Can't Ignore You&lt;/li&gt;
&lt;li&gt;Essentialism&lt;/li&gt;
&lt;li&gt;Hooked&lt;/li&gt;
&lt;li&gt;Rework&lt;/li&gt;
&lt;li&gt;The 7 Habits of Highly Effective People&lt;/li&gt;
&lt;li&gt;The Miracle Morning&lt;/li&gt;
&lt;li&gt;The Almanack Of Naval Ravikant&lt;/li&gt;
&lt;li&gt;Wabi Sabi&lt;/li&gt;
&lt;li&gt;Ikigai&lt;/li&gt;
&lt;li&gt;Daily Stoic &lt;/li&gt;
&lt;li&gt;Courage Is Calling&lt;/li&gt;
&lt;li&gt;Ego Is Enemy&lt;/li&gt;
&lt;li&gt;Make Time&lt;/li&gt;
&lt;li&gt;How To Win Friends And Influence People&lt;/li&gt;
&lt;li&gt;How To Stop Worrying And Start Living &lt;/li&gt;
&lt;li&gt;The Psychology of Money&lt;/li&gt;
&lt;li&gt;Rest: Why You Get More Done When You Work Less&lt;/li&gt;
&lt;li&gt;The Scout Mindset&lt;/li&gt;
&lt;li&gt;The 4 Hour Work Week&lt;/li&gt;
&lt;li&gt;Ultralearning&lt;/li&gt;
&lt;li&gt;This Is Marketing&lt;/li&gt;
&lt;li&gt;The Power Of Less&lt;/li&gt;
&lt;li&gt;On Writing Well&lt;/li&gt;
&lt;li&gt;The Manager Path&lt;/li&gt;
&lt;li&gt;Pragmatic Programmer&lt;/li&gt;
&lt;li&gt;The Go Programming Language&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Books written in Korean
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;무뎌진 감정이 말을 걸어올 때&lt;/li&gt;
&lt;li&gt;해변의 카프카 &lt;/li&gt;
&lt;li&gt;완전한 행복&lt;/li&gt;
&lt;li&gt;인생은 소설이다 &lt;/li&gt;
&lt;li&gt;책의 역습&lt;/li&gt;
&lt;li&gt;사이보그가 되다&lt;/li&gt;
&lt;li&gt;언어의 온도&lt;/li&gt;
&lt;li&gt;2인조&lt;/li&gt;
&lt;li&gt;보통의 존재&lt;/li&gt;
&lt;li&gt;울분&lt;/li&gt;
&lt;li&gt;니체의 말&lt;/li&gt;
&lt;li&gt;기억 1,2&lt;/li&gt;
&lt;li&gt;죽음 1,2&lt;/li&gt;
&lt;li&gt;문명 1,2&lt;/li&gt;
&lt;li&gt;달러구트 꿈 백화점 1,2&lt;/li&gt;
&lt;li&gt;미드나잇 라이브러리&lt;/li&gt;
&lt;li&gt;하루의 취향&lt;/li&gt;
&lt;li&gt;오늘 밤, 세계에서 이 사랑이 사라진다해도&lt;/li&gt;
&lt;li&gt;오늘은 이만 좀 쉴게요&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I didn't expect I could read this much when I started this year. I ended up reading more than 50 books. The numbers look amazing. The most beautiful thing is that books became the default mode. And I enjoy reading time more than screen time. So, if you want to make a habit of reading like me, don't overwhelm yourself with high expectations. Instead, start small. Start reading what you enjoy. And keep it. You can see the wonder over time. &lt;/p&gt;

</description>
      <category>books</category>
    </item>
  </channel>
</rss>
