<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Jinmu Go&apos;s Blog</title><description>A Smooth Sea Never Made a Skilled Sailor</description><link>https://jinmugo.com/</link><item><title>9oormthon 12th Participation Review</title><link>https://jinmugo.com/en/posts/12th-9oormthon/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/12th-9oormthon/</guid><description>9oormthon 12th Front Developer&apos;s Participation Review</description><pubDate>Fri, 20 Dec 2024 02:40:24 GMT</pubDate><content:encoded>&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;I participated as a front-end developer in the 12th edition of 9oormthon, which ran from December 10, 2024 to December 13, 2024.
In addition to my personal recollection of my first hackathon, I wrote this post to help prospective goormoners.&lt;/p&gt;
&lt;h2&gt;Motivation to participate&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;collaboration with other professions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the process of IT service development, I wanted to experience understanding the output of planners and designers and develop ideas together by requesting modifications or adding opinions.
Conversely, I wanted to participate because I wanted to have the experience of explaining the problems that may arise during the programming process so that the planners and designers could understand.
At &lt;a href=&quot;https://42seoul.kr&quot;&gt;42seoul&lt;/a&gt;, where I first learned programming, I mainly collaborated with people who worked in development or learned development, so at this Goormathon, I wanted to collaborate with people who had less understanding of development and practice explaining complex situations to them in an easy way.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fast and accurate product development training&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the real world, you have to set deadlines and develop products accordingly.
I participated in Goormathon to practice both speed and accuracy through intensive immersion.&lt;/p&gt;
&lt;h2&gt;Write an application&lt;/h2&gt;
&lt;p&gt;The application has a total of &lt;strong&gt;5 common items&lt;/strong&gt; + &lt;strong&gt;1 item specific to the development job&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Motivation for participating in Goormathon&lt;/li&gt;
&lt;li&gt;social issues facing Jeju Island recently&lt;/li&gt;
&lt;li&gt;service ideas to solve the above problems&lt;/li&gt;
&lt;li&gt;Your own strengths to lead flexible collaboration.&lt;/li&gt;
&lt;li&gt;Goal for &apos;growth&apos; in Goormathon&lt;/li&gt;
&lt;li&gt;Description of projects you have worked on.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I wrote my application with &lt;strong&gt;a little more focus on 2, 3, and 6&lt;/strong&gt; of the above items.&lt;/p&gt;
&lt;p&gt;**Problem Definition + Solution Proposal
I thought that items 2 and 3 were presented to see the ability to accurately diagnose the problem and then solve it.
Since many services have been developed and many plans have been made in the past 12 years of Goormtone, I thought that the problem definition would not be new anymore. Therefore, I spent more time on presenting service ideas to solve the problem. I thought it was more important to present ideas on how to solve this problem correctly.&lt;/p&gt;
&lt;p&gt;**Motivation and goals of the project
Item 6 was to describe the projects they have worked on before.
I was going to introduce some of the projects I worked on at &lt;a href=&quot;https://42seoul.kr&quot;&gt;42seoul&lt;/a&gt; (&lt;a href=&quot;https://github.com/WebWaveMaker/webserv&quot;&gt;webserv&lt;/a&gt;, &lt;a href=&quot;https://github.com/42ForYou/ft_transcendence&quot;&gt;ft_transcendence&lt;/a&gt;, etc.), but since they all solved a given problem, I didn&apos;t think I could explain my motivation and goals for the project very well. Therefore, I introduced the &lt;a href=&quot;https://github.com/JinMuGo/obsidian-go-up&quot;&gt;obsidian-go-up&lt;/a&gt; project, which was a simple plugin for Obsidian that was born out of my own frustrations.
I&apos;ve tried to convey as much as I can in this post about my motivation for the project and how I tried to solve it.&lt;/p&gt;
&lt;p&gt;Within 4 days of submission, I received an acceptance email and was able to participate in the goormathon.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Schedule&lt;/h2&gt;
&lt;p&gt;Here are the main events for each day&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Day 1&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Main Schedule&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Day 1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hackathon Lecture, 3-minute Self PR, Ideation Topic Presentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Day 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2-minute IDEATION, Team Building, Beer Party&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Day 3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hackathon run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Day 4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hackathon presentation, results announcement and awards&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Day 0&lt;/h3&gt;
&lt;p&gt;I arrived in Jeju Island on the afternoon of December 09th, the day before, and prepared to participate.&lt;/p&gt;
&lt;h3&gt;Write a self-introduction&lt;/h3&gt;
&lt;p&gt;I had to create a bio page on Notion because I had to perform a 3-minute Self PR on the first day of Goormathon.
I&apos;m not very good at introducing myself, so I was most afraid of the Self PR on the first day. I had to give presentations since I was in school, and my ears and face would turn red just getting up from my seat, so I often avoided presentations. However, I realized that I couldn&apos;t even convince others if I avoided it just because I couldn&apos;t give a presentation. So I wanted to get better this time, so I searched for the keyword &quot;self-presentation&quot; in the library and read the book 18-second self-presentation method [^self-pr-book], and wrote a self-presentation page based on the book and prepared for the presentation.&lt;/p&gt;
&lt;p&gt;Early in the book, the author says&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note] The 18-second elevator pitch.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A bio is not about introducing yourself, it&apos;s about introducing the future the listener can gain from your involvement.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Following this advice, I&apos;ve written my bio in such a way that it&apos;s about what the listener can gain from my experience. In other words, I structured my bio around the listener, not me, so I positioned myself as the pacer of the cloud talkers and tried to convey a metaphorical message to others, &quot;It would be great to team up with me and collaborate!&quot;&lt;/p&gt;
&lt;p&gt;Below is the bio page I wrote.&lt;/p&gt;
&lt;p&gt;
After I finished writing both the bio page and the script, I went to sleep.&lt;/p&gt;
&lt;h2&gt;Day 1&lt;/h2&gt;
&lt;p&gt;Day 1 consisted of hackathon lectures and presentations on the topics of Self PR and Foundations.&lt;/p&gt;
&lt;h3&gt;Hackathon Lecture&lt;/h3&gt;
&lt;p&gt;Hackathon with open source excitement&lt;/p&gt;
&lt;p&gt;Before the Goormathon. We had a lecture that gave us an overview of what kind of mindset we should have for the hackathon.&lt;/p&gt;
&lt;p&gt;In particular, the importance of selection and focus was emphasized due to the nature of hackathons where you have to develop a product in a short time.
Therefore, we introduced how to develop quickly by utilizing already developed open source or how to quickly materialize ideas by utilizing design tools such as Lean Canvas.&lt;/p&gt;
&lt;p&gt;In the MVP development process, we emphasized the following points.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prioritize speed over perfection: Focus on implementing ideas quickly rather than developing a perfect product.&lt;/li&gt;
&lt;li&gt;Focus on one thing rather than a broad interest: Focus on the right features (functionality) and measure the success of those features.&lt;/li&gt;
&lt;li&gt;Agility instead of waterfall: Don&apos;t focus on process and procedure, prioritize speed with division of labor and collaboration.&lt;/li&gt;
&lt;li&gt;Practicality, not more features: Don&apos;t boast as many features as possible, but provide specific value to users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Obviously, we had to develop a small service in a short period of time, so we realized that it was important to focus on one thing we wanted to offer and deliver it with perfection, rather than trying to develop everything.&lt;/p&gt;
&lt;p&gt;Also, the hackathon taught us some things not to do, and one of them was to &lt;strong&gt;just work hard&lt;/strong&gt;.
He emphasized that we shouldn&apos;t just focus on building and implementing something, and not forget the context of &lt;strong&gt;why and how our team is doing what we are doing&lt;/strong&gt;. This is not just for hackathons.
I took this to heart and went into Goormathon with it in mind because it&apos;s similar to what I ultimately wanted to accomplish in this hackathon.&lt;/p&gt;
&lt;h3&gt;Self PR&lt;/h3&gt;
&lt;p&gt;After the lecture and lunch, we had a 3-minute self-pitch.&lt;/p&gt;
&lt;p&gt;I memorized a script that I had prepared the day before and presented it. I was able to break the ice and relax while listening to other people&apos;s presentations.
Since it was a hackathon in Jeju Island, everyone was from so many different places, and I realized that I wouldn&apos;t have been able to meet such a diverse group of people if it was held in Seoul.
I was too nervous to listen to other people&apos;s presentations, but if I had this opportunity again, I would work harder to prepare my presentation and listen to other people&apos;s presentations more intently.&lt;/p&gt;
&lt;p&gt;Below is my full bio.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!quote]+ bio&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello, I&apos;m Jinmoo Go, a front-end developer who wants to be a pacemaker for goormonster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This Goormathon is a special opportunity for me. It is because I can team up with experts in various fields and learn together from planning to deployment. Especially, I think it will be really valuable to have the experience of understanding and communicating with planners and designers for the first time. I hope to create a meaningful time to achieve a common goal through this process.&lt;/p&gt;
&lt;p&gt;That&apos;s why I&apos;m going to be a pacemaker in this Goormathon. A pacemaker doesn&apos;t just run ahead of the team, but also understands the status and needs of the team members and acts accordingly. I thought that the ability of a pacemaker to understand the other person and decide my behavior accordingly is also functional in Goormathon.&lt;/p&gt;
&lt;p&gt;My name is written as &apos;Moo to touch&apos; on &apos;Jin to calm down&apos;, which means &apos;true Jin&apos; is a spinner, and &apos;Moo to touch&apos; is written as &apos;Handoja&apos; on &apos;nothing&apos;, which means &apos;touching something that is not there&apos;, which means to touch the heart. Since I became a programmer, I thought that I would spend my life creating something that touches people&apos;s hearts, and I would like to create something wonderful with you in this Goormathon. If you want to build a great team, feel free to reach out. I hope we can create a great experience together. Thank you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Hackathon Lecture - How to Grow from a Hackathon&lt;/h3&gt;
&lt;p&gt;After the introductions, there were other hackathon lectures, which talked about how to grow in a hackathon. One that stood out in my mind was the talk about &lt;code&gt;DONE&lt;/code&gt; and &lt;code&gt;PERFECT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;He said that most of us tend to perceive DONE as not being perfect, and PERFECT as not being done.
In a hackathon, everyone has a different definition of DONE, so DONE and PERFECT are not polar opposites.&lt;/p&gt;
&lt;p&gt;And in between DONE and PERFECT is GROWTH. Moving from your current state of being between DONE and PERFECT to getting closer to PERFECT is called growth.&lt;/p&gt;
&lt;p&gt;Hence, &quot;PERFECTLY DONE.&quot; Every moment of the hackathon. You said to aim to get it done as close to perfect as possible.&lt;/p&gt;
&lt;p&gt;This lecture is said to be based on Chiksent Mihai&apos;s &amp;lt;Immersion&amp;gt;&lt;a href=&quot;%5BImmersion%5D(https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=503603)&quot;&gt;^1&lt;/a&gt;, if you&apos;re interested, you might want to read it.&lt;/p&gt;
&lt;h3&gt;Announcing the foundation topic&lt;/h3&gt;
&lt;p&gt;At the end of Day 1, we had the announcement of the foundation topic.
The topic for this 12th edition was &quot;Aging&quot;.&lt;/p&gt;
&lt;p&gt;When I wrote my application, I presented a service related to aging, so I made a PPT that was a little more advanced.&lt;/p&gt;
&lt;h3&gt;End of Day 1&lt;/h3&gt;
&lt;p&gt;On Day 1, I went out for a walk with my teammates in the middle of the day and had a good time eating black pork with other Goormoners in the evening. During Goormathon, you don&apos;t get to go outside that much. I recommend that you move around a lot from day 1. Sometimes it doesn&apos;t feel real to be in Jeju Island.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Day 2&lt;/h2&gt;
&lt;p&gt;Day 2 started with a team-building and beer party, followed by the
2-minute ideation time, team building, and a beer party.&lt;/p&gt;
&lt;h3&gt;2-minute IDEATION&lt;/h3&gt;
&lt;p&gt;You have 2 minutes to present your idea on one page of PPT.
I proposed a service called &apos;Gilbot&apos;. I presented &lt;strong&gt;1-minute problem definition&lt;/strong&gt; &lt;strong&gt;1-minute solution&lt;/strong&gt; with a big framework.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since the presentation time was short and I only had one PPT, I was able to present with less tension than yesterday.
Afterward, I listened to other people&apos;s presentations and thought about what kind of people and ideas I would like to team up with.&lt;/p&gt;
&lt;h3&gt;Team building&lt;/h3&gt;
&lt;p&gt;The team building time was like a marketplace. There was no system, we just asked each other who we wanted to team up with and formed a team.&lt;/p&gt;
&lt;p&gt;I had already made a list of people I wanted to work with while listening to the foundation, and I was lucky enough to have no trouble organizing my team. If you&apos;re going to participate in a goormathon, I would recommend that you think about who you want to team up with and what ideas you want to bring to the table during the team building time.
There is a certain amount of &apos;luck&apos; that comes into play during this time, and we were often teamed up with people who were relatively close to each other based on our initially randomized seat assignments.&lt;/p&gt;
&lt;p&gt;So if you have a goal or outcome you want, it&apos;s important to be proactive about it. You&apos;ll be more satisfied with the outcome if you make the move and team up with someone rather than hoping they&apos;ll come to you.&lt;/p&gt;
&lt;p&gt;That&apos;s how our team, &quot;&lt;a href=&quot;https://github.com/ddol-mang&quot;&gt;&lt;strong&gt;Olmangolmangolmangolmang&lt;/strong&gt;&lt;/a&gt;&quot; was formed. Our organizer came up with the team name out of the blue, and we all liked it so much that we decided to stick with it.&lt;/p&gt;
&lt;p&gt;A bunch of old ladies gathered for old ladies, doesn&apos;t that sound good?&lt;/p&gt;
&lt;p&gt;After the team was formed, we had a brainstorming session to select topics that fit the theme of &apos;Jeju Island&apos;, &apos;Cloud&apos;, and &apos;Aging&apos;. However, it was not easy to select services that fit the theme.
We couldn&apos;t fundamentally solve the social problem of aging, so we decided to develop a service that could alleviate or solve the problems caused by aging.&lt;/p&gt;
&lt;p&gt;However, we ended up at the beer party at 6pm with no good ideas.&lt;/p&gt;
&lt;h3&gt;Beer Party&lt;/h3&gt;
&lt;p&gt;In addition to the formed team, we had a beer party to connect with other team members and mentors.&lt;/p&gt;
&lt;p&gt;Beer parties were based on three different timetables.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a time to chat with people sitting in randomly assigned seats (6:00-7:30)&lt;/li&gt;
&lt;li&gt;free-flowing conversations at tables divided by job function - with mentor participation (7:30-9:00)&lt;/li&gt;
&lt;li&gt;free time to chat with other team members (9-11)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This was one of my favorite parts of the hackathon. It was fun to talk to other people who came to the Goormathon, and I was able to think about various things while listening to their stories.
I think Goormathoners who participate in Goormathon should spend at least as much time talking and networking with other people at the beer party as they do at the hackathon to get 200% out of it.&lt;/p&gt;
&lt;h3&gt;Decide on a topic&lt;/h3&gt;
&lt;p&gt;After the beer party, we got back together and decided on a topic with our teammates. We had to choose a topic before we started the hackathon tomorrow.
I think we talked about a lot of things. Services for seafarers. Connecting the elderly and the young. A service using grandma and grandpa&apos;s house like a temple stay, and many other topics were discussed but dismissed for various reasons.
We chose the topic based on &lt;a href=&quot;https://www.jejunews.com/news/articleView.html?idxno=2215293&quot;&gt;a newspaper article&lt;/a&gt; that was published on the day of the hackathon that one of the team members found.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!quote]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In other words, when it comes to the happiness of the elderly, their children are healthy, their children are married and living in harmony, and they continue to be active as long as their bodies allow.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;... (emphasis added)&lt;/p&gt;
&lt;p&gt;&quot;Relationship with children&quot; is more important than living standards or current life in terms of life satisfaction.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In short, older adults in Jeju Island have their children at the center of their happiness, but they are relationship-oriented rather than dependent, explore independence and meaning in life through work, and value their children&apos;s health and happiness more than their own.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;The above article made us realize that there is a need for a connection between Jeju parents and their mainland children, and to solve this problem, we decided to develop a platform for parents and children to communicate their current status through simple interactions.&lt;/p&gt;
&lt;p&gt;The topic was chosen because everyone on the team felt empathy and excitement for this problem. Personally, I was overwhelmed when the topic was first decided.
The process of brainstorming and refining the idea was hard, but we were having so much fun that we stayed up until 4am.
I was worried before the hackathon started because I&apos;m a light sleeper and a night owl, but I was so engrossed that it didn&apos;t matter.&lt;/p&gt;
&lt;p&gt;Afterward, we decided to go to our rooms to sleep for the hackathon tomorrow. We were all worried about oversleeping, so we shared our rooms on KakaoTalk with our teammates and went to bed.&lt;/p&gt;
&lt;h2&gt;Day 3&lt;/h2&gt;
&lt;p&gt;After the topic was selected, we had a meeting to develop a specific service, and we made API, DB specification, and front-end development plan according to the designer&apos;s screen design.&lt;/p&gt;
&lt;p&gt;Since I was not yet familiar with libraries such as react-query and zustand, I asked another front-end developer to focus on the screen implementation + back-end API, and I was in charge of the screen implementation + deployment environment of the front-end stage.&lt;/p&gt;
&lt;p&gt;During the development process, I noticed that our deployed service kept re-rendering every few seconds. I found the problem around 4am, and after about 2 hours of troubleshooting, I realized that our service was running in development mode.
I realized that this was the problem and wanted to change it to production mode, but I didn&apos;t understand the crampoline (deployment environment), so I asked my mentors for help.
My intentions were simple. The service was developed with VITE and I wanted to change the service, which was originally running in development mode, to run in production mode. Here&apos;s how it happened&lt;/p&gt;
&lt;p&gt;The backend developer was not familiar with crampoline and had difficulty deploying it, so we had to find a way to do something other than spinning up a static server with nginx, which is what we originally wanted to do.
So the backend guy asked his mentor for help, and that&apos;s how we ended up spinning up the frontend code in development mode (e.g. &lt;code&gt;pnpm dev&lt;/code&gt;) rather than the logic of serving static files with nginx after the original static build.
VITE has an &lt;code&gt;images&lt;/code&gt; command that serves static files into production. It occurred to me that this wouldn&apos;t have happened if I had added a more intuitive production-ready script to the &lt;code&gt;package.json&lt;/code&gt; &lt;code&gt;script&lt;/code&gt;, such as &lt;code&gt;start&lt;/code&gt; instead of &lt;code&gt;images&lt;/code&gt;. It was a good reminder of the importance of abstraction.&lt;/p&gt;
&lt;p&gt;In the meantime, the planners and designers were preparing for the presentation, and I apologized to them for not being able to participate much in the process.
By 10 o&apos;clock the next day, the presentation preparation and development were finalized.&lt;/p&gt;
&lt;p&gt;Seongsan Sunrise Peak, which we visited during the hackathon.
And a photo with the team members.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Day 4&lt;/h2&gt;
&lt;p&gt;Day 4 was the hackathon announcements and awards.&lt;/p&gt;
&lt;h3&gt;Hackathon presentation&lt;/h3&gt;
&lt;p&gt;We presented our service &quot;&lt;a href=&quot;https://github.com/ddol-mang/hey-oldlady&quot;&gt;Hey, Grandma&lt;/a&gt;&quot;, which we had been working on all night.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Our presentation strategy was to appeal to the emotions of parents and children living apart from their parents.
We presented the problem through news and statistics, and introduced a service to solve it.&lt;/p&gt;
&lt;p&gt;However, in the feedback from the presentation, you raised the question of whether the features and problems we presented were &lt;strong&gt;actually needed by users&lt;/strong&gt;.
We thought a lot about this, but we were disappointed that we didn&apos;t create a logic that could explain it well enough.
However, we&apos;re really glad that our service focused on user experience and &lt;strong&gt;aging&lt;/strong&gt; and that we focused on a simple user flow to solve it.&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;It was a great experience and a lot of learning in a very short time, true to the values that Goormtone has been promoting.&lt;/p&gt;
&lt;p&gt;It was my first hackathon, so there were a lot of unknowns, but I was able to meet great teammates and have a great time building memories together.
We worked so hard that we forgot to sleep at night, and we learned a lot in the process.
Personally, the first hackathon buttoned me up so well that I&apos;m eager to participate in other hackathons.&lt;/p&gt;
&lt;p&gt;There are many reasons to participate in a hackathon, but I think it&apos;s all about the experience. The process of intensely thinking and developing ideas with my teammates at the goormathon was purely enjoyable, and that alone made it worthwhile for me.&lt;/p&gt;
&lt;p&gt;So if you&apos;re on the fence about participating in a hackathon, I highly recommend it.
The networking with other cool people is a bonus.&lt;/p&gt;
&lt;p&gt;[^self-pr-book]: &lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=94177413&quot;&gt;18 Second Self-Pitch&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>goormthon</category><category>goormthon 12th</category><category>Hackathon</category><author>Jinmu Go</author></item><item><title>Amazon Q Developer CLI Quick Start Guide</title><link>https://jinmugo.com/en/posts/amazon-q-developer-cli/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/amazon-q-developer-cli/</guid><description>Installing Amazon Q Developer CLI, giving it a planning document as context, building a Pygame game, and reflecting on the experience.</description><pubDate>Wed, 04 Jun 2025 13:25:20 GMT</pubDate><content:encoded>&lt;p&gt;AWSKRUG alerted me to an event on creating a simple game with Amazon Q Developer, so I thought I&apos;d join in.
&lt;/p&gt;
&lt;p&gt;It&apos;s easy to participate.&lt;/p&gt;
&lt;p&gt;You create a game with the Amazon Q CLI, write a blog or make a video about how you did it, and submit the link to the form.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!info] How to participate&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 1&lt;/strong&gt; : Sign up to an AWS Builder ID and claim your unique community.aws username from &lt;a href=&quot;https://community.aws/builderid?trk=b085178b-f0cb-447b-b32d-bd0641720467&amp;amp;sc_channel=el&quot;&gt;this link.&lt;/a&gt; If you need help or network with other fellow builders, join the discord &lt;a href=&quot;https://discord.gg/KNC9JQAfKT&quot;&gt;server from this link&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 2&lt;/strong&gt; : &lt;a href=&quot;https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html&quot;&gt;Install Amazon Q CLI&lt;/a&gt; in your machine. Here are two guides from Ricardo Sueiras on how you can install in &lt;a href=&quot;https://community.aws/content/2ulGwNwLFj5grS8hXJBMCN78Qwl/the-essential-guide-to-installing-amazon-q-developer-cli-on-linux?trk=6f6cb092-f1ba-456b-8644-73ed7ccbd567&amp;amp;sc_channel=el_&quot;&gt;Linux&lt;/a&gt; and in &lt;a href=&quot;https://community.aws/content/2v5PptEEYT2y0lRmZbFQtECA66M/the-essential-guide-to-installing-amazon-q-developer-cli-on-windows?trk=e07eca93-fa2f-4351-b567-f293b83eb635&amp;amp;sc_channel=el_&quot;&gt;Windows&lt;/a&gt;. Install &lt;a href=&quot;https://www.pygame.org/wiki/GettingStarted&quot;&gt;PyGame&lt;/a&gt; or some other gaming library on your laptop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 3&lt;/strong&gt; :Start a chat session with Amazon Q CLI and build a game with just prompts in the chat. Try to be innovative as possible with your game so you explore the possibilities of Amazon Q CLI.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 4&lt;/strong&gt; : Write a blog about what you&apos;ve built or create a video about it. Make a public post in a social media of your liking with the hashtag #AmazonQCLI. It can be in your local language, which we encourage. Optionally you can also host your code in a &lt;a href=&quot;https://github.com/&quot;&gt;github&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;STEP 5&lt;/strong&gt; : &lt;a href=&quot;https://pulse.aws/survey/ZO9G4AEL&quot;&gt;Fill this T shirt redemption form&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since we need to create a game, we first need to install the Amazon Q Develop CLI.
It looks like it can only be installed on macOS and Linux-based OSes by default. Windows needs to use WSL. You can find detailed installation instructions at the link below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Installing Amazon Q for command line - Amazon Q Developer&quot;
image: &quot;https://docs.aws.amazon.com/assets/r/images/aws_logo_light.svg&quot;
description: &quot;Learn how to install Amazon Q Developer for command line on different operating systems including macOS, Linux, and Windows Subsystem for Linux (WSL).&quot;
url: &quot;https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installing and typing &lt;code&gt;q&lt;/code&gt; in the terminal, you should see something like this!
&lt;/p&gt;
&lt;h2&gt;Time To Create&lt;/h2&gt;
&lt;p&gt;After completing the installation, we need to create the game, and since I don&apos;t use Python very often and don&apos;t know anything about Pygame, I really let &lt;code&gt;q&lt;/code&gt; do all the coding logic and image generation.&lt;/p&gt;
&lt;p&gt;I had a planning document from a previous school class where I had designed a game, and I gave it to GPT, who recreated it in English markdown and gave it to AWS Q.&lt;/p&gt;
&lt;p&gt;It was a game plan called Elysian-Arcana, and I was wondering how to give it to amazon q, so I looked at the &lt;code&gt;/help&lt;/code&gt; function of amazon q, and there was a command called &lt;code&gt;context&lt;/code&gt;, so I was able to provide context.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So I put my game plan document in the context of Q and asked him to create a mini-game based on this markdown document.&lt;/p&gt;
&lt;p&gt;He created a roguelike, turn-based card game.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;They did a good job, but it&apos;s still really cool to see an AI make a turn-based game. It still lacks a lot of details and gameplay, but it&apos;s still cool to see something that was made with just vibe coding.&lt;/p&gt;
&lt;p&gt;
To make it a bit more gameable, it lets you pick a card after you clear a stage.&lt;/p&gt;
&lt;p&gt;After five stages, my characters have leveled up, their mana barrels have increased, their health has increased, and they now show the intent of their opponent&apos;s attacks. You can also see that I&apos;ve taken care of the game&apos;s convenience.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s exciting to be able to make a game like this, but it&apos;s also a little disappointing.
I asked it to keep creating and linking pictures of the opponent&apos;s monsters about 3 times, but it didn&apos;t keep doing it because I didn&apos;t write the prompt well enough, and the images of all the cards were the same.&lt;/p&gt;
&lt;p&gt;But it&apos;s amazing how far we&apos;ve come. I was really surprised that they got it to this point, because I kept asking for things like feature and screen definitions without knowing anything about the implementation details.&lt;/p&gt;
&lt;p&gt;It&apos;s free to use, so if you&apos;re interested, you might want to give it a try. I&apos;ve attached the source code below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;GitHub - JinmuGo/elysian_arcana_aws_q: build game with aws q&quot;
image: &quot;https://opengraph.githubassets.com/d0cf93f2488e20f0c8ccd3df91300d029b5f4bfc5f2e02ab63a5acd186bd0c03/JinmuGo/elysian_arcana_aws_q&quot;
description: &quot;build game with aws q. Contribute to JinmuGo/elysian_arcana_aws_q development by creating an account on GitHub.&quot;
url: &quot;https://github.com/JinmuGo/elysian_arcana_aws_q&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>AmazonQCLI</category><category>AWS</category><author>Jinmu Go</author></item><item><title>[CLF-C02] AWS Cloud Practitioner Certification Review</title><link>https://jinmugo.com/en/posts/aws-clf-c02/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/aws-clf-c02/</guid><description>How I prepared for AWS Cloud Practitioner CLF-C02, used official learning materials and practice exams, and handled the online-proctored test day.</description><pubDate>Thu, 22 May 2025 00:03:25 GMT</pubDate><content:encoded>&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;I&apos;ve been studying the cloud lately. While a certification is not a complete reflection of your skills, I wanted to see some progress, so I took the AWS Cloud Practitioner certification as a first step. In this article, I&apos;d like to share my experiences in preparing for this certification, as well as tips and tricks for studying efficiently.&lt;/p&gt;
&lt;h2&gt;How to study and prepare&lt;/h2&gt;
&lt;p&gt;I had a total preparation time of 2 months, but I didn&apos;t study properly because I had a lot of things going on. I think I studied in a rush until about a week before the exam.&lt;/p&gt;
&lt;h3&gt;Preparation sequence&lt;/h3&gt;
&lt;h4&gt;&lt;a href=&quot;https://explore.skillbuilder.aws/learn/courses/13522/aws-cloud-practitioner-essentials-hangug-eo&quot;&gt;AWS official study material (AWS Skill Builder)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;AWS has created a course for Cloud Practitioners, and I don&apos;t think there&apos;s a better one out there. It&apos;s easy to understand, whether you&apos;re new to the cloud or already familiar with it. If you&apos;re looking to get into the cloud for the first time, I highly recommend watching this course.&lt;/p&gt;
&lt;p&gt;At the end of each module, he provides links to whitepapers related to that concept, which are very helpful if you want to study them after the module.&lt;/p&gt;
&lt;h4&gt;&lt;a href=&quot;https://explore.skillbuilder.aws/learn/courses/16814/aws-certified-cloud-practitioner-official-practice-question-set-clf-c02-hangug-eo/lessons&quot;&gt;AWS Certified Cloud Practitioner Official Practice Question Set (CLF-C02 - English)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Then you&apos;ll have 20 simple questions to work through. It&apos;s from AWS, so the questions are well explained and I can see at a glance which questions I&apos;m spending a lot of time on and which concepts I&apos;m lacking.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a href=&quot;https://www.udemy.com/course/aws-certified-cloud-practitioner-new/&quot;&gt;Stephane Maarek&apos;s course on Udemy&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This is the most popular Cloud Practitioner course on udemy. You can go through the two courses above and figure out which concepts you&apos;re lacking and then listen to just those parts. If you have time, you can also listen to it from start to finish. It goes into a little more detail than the official AWS study materials, and I highly recommend taking the practice exam in Section 22. I took this practice test five times before I took the exam, and I think you&apos;ll ace it if you familiarize yourself with the concepts and usage associated with the questions here.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h4&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=T17iGqvYi6s&quot;&gt;AWS Classroom Youtube&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;If you&apos;re taking the AWS certification exam for the first time, I recommend watching the videos above. You&apos;ll learn a lot about the exam and the certification.&lt;/p&gt;
&lt;h2&gt;Exam day (online exam)&lt;/h2&gt;
&lt;p&gt;I took the exam from home as an online proctored exam. I was a bit nervous about taking the exam at home.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;prepare my ID (passport)&lt;/li&gt;
&lt;li&gt;keep a clean desk environment&lt;/li&gt;
&lt;li&gt;Prepare and organize your surroundings beforehand as you will have to show your surroundings to the proctor on camera&lt;/li&gt;
&lt;li&gt;check the internet connection (stable network environment is essential)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I had a tumbler on my desk, but they didn&apos;t really punish me for it. Other reviews said that the proctor asked me to do a lot of things, but I just said &quot;show me your desk -&amp;gt; show me your wrist -&amp;gt; put your phone out of reach&quot; and then went straight into the exam.&lt;/p&gt;
&lt;p&gt;I had an Indian proctor come in and his accent was hard to understand, but if it seemed like he wasn&apos;t getting it, he would write it down in chat and I was still able to proceed.&lt;/p&gt;
&lt;h2&gt;Exam tips&lt;/h2&gt;
&lt;p&gt;The exam is 90 minutes + (30 minutes for Korean-specific settings). There are 65 questions. Before going into the exam, it&apos;s a good idea to have an idea of how many questions you need to get wrong to pass. For example, for the CLF-C02 exam, 700 is a passing score and you need to get about 45 questions right out of 65, which means that there shouldn&apos;t be more than 20 questions that you&apos;re not sure of the answer to during the exam. Knowing this ahead of time gives you a little more confidence going into the exam.&lt;/p&gt;
&lt;p&gt;It&apos;s been 50 minutes since you&apos;ve completed all the questions.
After a few rounds of review, I finished the exam with 20 minutes left and 8 questions flagged.
The exam results are instant, and you&apos;ll receive a follow-up email with detailed results.&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;I took the exam at 10 (5/21) and finished at 11:10, credly emailed me at 20 and AWS emailed me at 6 the next day (5/22) with details.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Although it was a relatively short period of time, I was able to clear up some of my vague knowledge of the cloud while preparing for the certification. Based on this experience, I&apos;m going to take the AWS Certified DevOps Engineer - Professionala challenge right away.
I hope this article will be of some help to those who are starting to study the cloud or preparing for the certification.&lt;/p&gt;
</content:encoded><category>AWS</category><category>CLF-C02</category><author>Jinmu Go</author></item><item><title>How to apply blog comment function With Fuma Comment</title><link>https://jinmugo.com/en/posts/blog-comment-feautre-with-fuma-comment/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/blog-comment-feautre-with-fuma-comment/</guid><description>A review of an incomplete commenting feature, rebuilt cleanly with Fuma Comment.</description><pubDate>Thu, 01 May 2025 01:46:46 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!attention]
This article references &lt;a href=&quot;https://fuma-comment.vercel.app/docs&quot;&gt;fuma-comment Docs&lt;/a&gt; and &lt;a href=&quot;https://github.com/fuma-nama/fuma-comment&quot;&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;I was following github and saw that &lt;a href=&quot;https://github.com/velopert&quot;&gt;velopert&lt;/a&gt; had starred a project.
&lt;/p&gt;
&lt;p&gt;It was a project called &lt;a href=&quot;https://github.com/fuma-nama/fumadocs&quot;&gt;fumadocs&lt;/a&gt; by [fuma-nama]. It&apos;s a documentation framework based on next.js, it&apos;s well-designed and most importantly, it makes documentation really simple. It was amazing. So, while I was spying on him, another project caught my eye.
&lt;/p&gt;
&lt;p&gt;It was a project called &lt;a href=&quot;https://github.com/fuma-nama/fuma-comment&quot;&gt;fuma-comment&lt;/a&gt;, and the description said.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;user friendly, beautiful comment area to your blog&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I thought, &quot;This is it!&quot; because I&apos;ve been having a lot of trouble with my blog&apos;s commenting functionality lately...&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When I first built the commenting feature, I thought, **I want anyone to be able to come and comment without having to log in, so I removed OAuth, ID/PW, email, magic links, etc. as much as possible, so that people could CRUD their comments with just their &lt;strong&gt;IP&lt;/strong&gt;... But this was problematic 😞.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;it was possible to manipulate other people&apos;s comments in situations where IPs are shared, such as in public places.&lt;/li&gt;
&lt;li&gt;a person&apos;s IP is not static. You could write a comment yesterday and not see the edit button today.&lt;/li&gt;
&lt;li&gt;Can be exploited by spoofing/proxying. It&apos;s really easy to steal that IP with a VPN/proxy.&lt;/li&gt;
&lt;li&gt;No notification/response. We can&apos;t identify you by your IP, and we don&apos;t know your email address.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After writing this, I wonder why I implemented only IP. Looking back, I think I implemented it because I wanted to make it easier for anyone to see my posts and leave comments, even though it was too easy. I also implemented giscus, but I was disappointed that it was difficult to customize the theme and required a github ID to use it.&lt;/p&gt;
&lt;p&gt;So, after seeing the above project, I was convinced. You can plug in various authenticators such as next-auth, better-auth, and clerk auth, and you can customize various functions such as mention, reply, and notification.&lt;/p&gt;
&lt;p&gt;You can test the project yourself through the link below, or leave a comment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Fuma Comment&quot;
image: &quot;https://avatars.githubusercontent.com/u/104714237?v=4&quot;
description: &quot;A React.js library for adding comment area to anywhere, with your own backend &amp;amp; auth!&quot;
url: &quot;https://fuma-comment.vercel.app/&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I decided to adapt this project to my own blog. For now, I&apos;m going to implement it simply with Github OAuth and later I&apos;ll convert it to magic link or something else.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;client: &lt;strong&gt;nextjs 15&lt;/strong&gt; with &lt;strong&gt;Route Handler&lt;/strong&gt;.
database: &lt;strong&gt;postgres&lt;/strong&gt;
ORM: &lt;strong&gt;prisma&lt;/strong&gt;
ObjectStorageService: &lt;strong&gt;uploadthing&lt;/strong&gt; (based on S3)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]
Cannot be used with the &lt;code&gt;export: output&lt;/code&gt; option in &lt;code&gt;next.config.mjs&lt;/code&gt; because it uses &lt;strong&gt;Route Handler&lt;/strong&gt; to process new requests each time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Library&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;@fuma-comment/react&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@fuma-comment/server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@prisma/client&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prisma&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uploadthing&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Signin Flow&lt;/h3&gt;
&lt;p&gt;
Inspired From: https://medium.com/@enes9103/building-apis-and-handling-authentication-with-next-js-9d4a8b448251&lt;/p&gt;
&lt;h3&gt;Comment Flow&lt;/h3&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;---]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#db&quot;&gt;DB&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Prisma&lt;/li&gt;
&lt;li&gt;Postgres DB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#nextjs-route-handler&quot;&gt;NextJS Route Handler&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;NextAuth&lt;/li&gt;
&lt;li&gt;uploadthing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#nextjs-client&quot;&gt;NextJS Client&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&apos;s describe the implementation in order.&lt;/p&gt;
&lt;h2&gt;DB&lt;/h2&gt;
&lt;p&gt;Prepare one postgresDB, you can use the DB Provider in vercel or install it directly on your server or float it using docker.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m using Coolify, so. I spun up a container via docker on a remote server.
&lt;/p&gt;
&lt;p&gt;And make it public so that this DB can be accessed remotely. Allow the port on your firewall, and if it&apos;s docker, proceed with port binding.&lt;/p&gt;
&lt;p&gt;If you succeeded in exposing the DB, try to access the DB with a client tool like &lt;code&gt;psql&lt;/code&gt;. The URI of postgres is as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;postgres://{POSTGRES_USERNAME}:{SERVICE_PASSWORD_POSTGRES}@{YOUR_HOST}:{POSTGRES_PORT}/{POSTGRES_DB}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now we will access this postgres public URI in our Route Handler.
There&apos;s something we need to do before that.&lt;/p&gt;
&lt;p&gt;Link to the &lt;code&gt;prisma/schema.prisma&lt;/code&gt; route and paste the following code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;fuma-comment/apps/docs/prisma/schema.prisma at main - fuma-nama/fuma-comment&quot;
image: &quot;https://repository-images.githubusercontent.com/717080536/f375c8ab-da9a-4716-973e-92b47f38244a&quot;
description: &quot;user friendly, beautiful comment area to your blog - fuma-nama/fuma-comment&quot;
url: &quot;https://github.com/fuma-nama/fuma-comment/blob/main/apps/docs/prisma/schema.prisma&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bind the postgres URI to the &lt;strong&gt;&lt;code&gt;DATABASE_URL&lt;/code&gt;&lt;/strong&gt; environment variable and use the &lt;strong&gt;&lt;code&gt;prisma db push&lt;/code&gt;&lt;/strong&gt; command to reflect the current state of the Prisma schema file directly to the database.&lt;/p&gt;
&lt;h3&gt;NextJS Route Handler&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;/api&lt;/code&gt; folder structure is shown below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/api
├── /auth
│ └── [...nextauth]
│ ├── options.ts
│ └── route.ts
├── /comments
│ └── [...comment]
│ └── route.ts
├── uploadthing
    ├── core.ts
    └── route.ts
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;fuma-comment/apps/docs/app/api at main - fuma-nama/fuma-comment&quot;
image: &quot;https://repository-images.githubusercontent.com/717080536/f375c8ab-da9a-4716-973e-92b47f38244a&quot;
description: &quot;user friendly, beautiful comment area to your blog - fuma-nama/fuma-comment&quot;
url: &quot;https://github.com/fuma-nama/fuma-comment/tree/main/apps/docs/app/api&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You just need to paste the files in the path and modify the paths.&lt;/p&gt;
&lt;h3&gt;Issue Github OAuth&lt;/h3&gt;
&lt;p&gt;Since NextAuth uses Github OAuth tokens, we&apos;ll need to use the&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;providers: [[.
	GithubProvider({
		clientId: env.GITHUB_ID, // highlight
		clientSecret: env.GITHUB_SECRET, // highlight
		profile(profile: GithubProfile) {
			return {
				id: profile.id.toString(),
				name: profile.name || profile.login,
				email: profile.email,
				image: profile.avatar_url,
			};
		},
	}),
],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OAuth must be issued and set up.&lt;/p&gt;
&lt;p&gt;Go to &lt;code&gt;profile -&amp;gt; Settings -&amp;gt; Developer Settings&lt;/code&gt; and you will see the screen below.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;From here, click &lt;code&gt;OAuth Apps&lt;/code&gt; to navigate to it. Tap &lt;code&gt;New OAuth app&lt;/code&gt; and select the&lt;/p&gt;
&lt;p&gt;If you&apos;re in a development environment, enter &lt;code&gt;localhost:3000&lt;/code&gt;.
If you are in a deployment environment, enter your deployment URL and add &lt;code&gt;/api/auth/callback/github&lt;/code&gt; to the callback URL.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
We recommend that you get separate OAuth for development and deployment environments so that they work separately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then get a Secret and bind the values of Client ID and Client Secret to the environment variables &lt;code&gt;GITHUB_ID&lt;/code&gt; and &lt;code&gt;GITHUB_SECRET&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;NextAuth&lt;/h3&gt;
&lt;p&gt;You&apos;ll also need to set the NextAuth environment variable. You can find them in the link below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Options | NextAuth.js&quot;
image: &quot;https://next-auth.js.org/img/logo/logo-xs.png&quot;
description: &quot;Environment Variables&quot;
url: &quot;https://next-auth.js.org/configuration/options#nextauth_secret&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;nextauth_url=http://localhost:3000
NEXTAUTH_SECRET=
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In particular, &lt;code&gt;NEXTAUTH_SECRET&lt;/code&gt; is set in &lt;code&gt;.env.local&lt;/code&gt; as &lt;code&gt;AUTH_SECRET&lt;/code&gt;, which is an alias of &lt;code&gt;NEXTAUTH_SECRET&lt;/code&gt;, when you run &lt;code&gt;npx auth secret&lt;/code&gt; in the root of your project, as you can see in the official documentation. You can just rename this and use it.&lt;/p&gt;
&lt;h3&gt;Uploadthing&lt;/h3&gt;
&lt;p&gt;Uploadthing is required to use images in comments. In the free tier, 2GB is provided by default. This seems to be enough for a simple blog, so I&apos;m using it for now. If I need more. I&apos;ll have to look into other options. cloudflare R2 is compatible with S3, so I guess I could use that.&lt;/p&gt;
&lt;p&gt;Anyway, you can sign up and log in at &lt;a href=&quot;https://uploadthing.com/&quot;&gt;homepage&lt;/a&gt;, then go to &lt;code&gt;Dashboard -&amp;gt; API Key&lt;/code&gt; and move &lt;code&gt;UPLOADTHING_TOKEN&lt;/code&gt; to the .env as it is.&lt;/p&gt;
&lt;p&gt;---]&lt;/p&gt;
&lt;p&gt;Now you are done with the configuration in Route Handler. The code is all taken from the official repo. The only thing we had to do was to set the env, and we have 6 env&apos;s in total.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DATABASE_URL=
GITHUB_ID=
GITHUB_SECRET=
NEXTAUTH_URL=
nextauth_secret=
uploadthing_token=
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;NextJS Client&lt;/h2&gt;
&lt;p&gt;And now create a component named &lt;code&gt;CommentsWithAuth&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;use client&quot;;

import { signIn } from &quot;next-auth/react&quot;;

import type { CommentsProps } from &quot;@fuma-comment/react&quot;;

import { Comments } from &quot;@fuma-comment/react&quot;;

import { createUploadThingStorage } from &quot;@fuma-comment/react/uploadthing&quot;;

const storage = createUploadThingStorage();

export function CommentsWithAuth(props: Omit&amp;lt;CommentsProps, &quot;auth&quot;&amp;gt;) {
  return (
    &amp;lt;Comments
      storage={storage}
      mention={{
        enabled: true,
      }}
      auth={{
        type: &quot;api&quot;,
        signIn: () =&amp;gt; void signIn(&quot;github&quot;),
      }}
      {...props}
    /&amp;gt;.
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;fuma-comment/apps/docs/app/(demo)/page.client.tsx at main - fuma-nama/fuma-comment&quot;
image: &quot;https://repository-images.githubusercontent.com/717080536/f375c8ab-da9a-4716-973e-92b47f38244a&quot;
description: &quot;user friendly, beautiful comment area to your blog - fuma-nama/fuma-comment&quot;
url: &quot;https://github.com/fuma-nama/fuma-comment/blob/main/apps/docs/app/(demo)/page.client.tsx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then &lt;code&gt;import&lt;/code&gt; it into the nextjs page (&lt;code&gt;page.tsx&lt;/code&gt;), layout (&lt;code&gt;layout.tsx&lt;/code&gt;), or component you want to apply it to, and you&apos;re done.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;CommentsWithAuth page={slug} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By setting the id or slug of each page in the page props, you can customize the comment box for each page. If you want to use the same comment area, you can set the page to the same value.&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;I&apos;ve created a comment function using &lt;code&gt;fuma-comment&lt;/code&gt; like this, and it&apos;s simple enough to use, but I think it&apos;s more useful because there are so many ways to customize it. Even if you have a little knowledge of NextAuth, prisma, and postgres DB, you can customize it to your liking, which is the best part of this project.&lt;/p&gt;
&lt;p&gt;I&apos;d like to thank &lt;a href=&quot;https://github.com/fuma-nama&quot;&gt;fuma-nama&lt;/a&gt; for creating such an awesome project, and I&apos;ll leave you with this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!seealso]
I&apos;m sure there are probably some things I missed while writing this post. Please feel free to leave a comment or mail me and I&apos;ll get back to you as soon as possible, thank you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;&lt;em&gt;added 2025-08-03&lt;/em&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
&lt;strong&gt;Announcing blog migration and feature changes&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The blog has now been moved to &lt;strong&gt;Astro&lt;/strong&gt;, and the commenting system is now using &lt;strong&gt;Giscus&lt;/strong&gt; again.
While fuma-comment is a great system, I&apos;ve reverted back to Giscus, which is better suited for static sites, so the &lt;code&gt;fuma-comment&lt;/code&gt; in this post is not currently applied to my blog, and I&apos;d appreciate it if you&apos;d refer to it for &lt;strong&gt;technical archiving purposes&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
</content:encoded><category>fuma-comment</category><category>postgres</category><category>nextatuh</category><category>prisma</category><category>uploadthing</category><category>github-oauth</category><author>Jinmu Go</author></item><item><title>About Books and Movies</title><link>https://jinmugo.com/en/posts/book-and-movie/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/book-and-movie/</guid><description>About books and movies</description><pubDate>Tue, 16 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;[!quote]&lt;/p&gt;
&lt;p&gt;Q. Nowadays, the means of expressing stories are expanding towards media such as movies and dramas instead of books, but is watching movies as helpful in cultivating &amp;gt; wisdom as reading books?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A. Movies are like alcohol, so to speak, and books are like water. Books make us cold in a good way, and movies make us hot in a good way, but reason is basically cold, so if I were to answer according to what you&apos;re saying, I would say, &quot;As far as education is concerned, movies will never catch up with books,&quot; because the nature of reason itself is more like water, not fire.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;My original major is film/video, so I watched a lot of movies in college and often wrote reviews and critiques of them, and as I continued to watch and read about them, I had a similar question to the one above. The movies I watched, such as &lt;a href=&quot;https://www.imdb.com/title/tt1216496/&quot;&gt;&amp;lt;Mother&amp;gt;&lt;/a&gt;, &lt;a href=&quot;https://www.imdb.com/title/tt0817225/&quot;&gt;&amp;lt;Milyang&amp;gt;&lt;/a&gt;, and &lt;a href=&quot;https://www.imdb.com/title/tt1287878/&quot;&gt;&amp;lt;Poetry&amp;gt;&lt;/a&gt;, impressed me more than any books I had ever read, because they instilled culture and wisdom in me. Speaking of &quot;getting under your skin,&quot; movies seem to require less cognitive effort from the audience than books. In other words, when we watch a movie, we don&apos;t have to imagine what the characters are doing, we just watch and listen to the director/writer&apos;s direction on the screen. Because the director/writer explains the story he/she wants to tell by borrowing from the world we live in and showing it in front of our eyes, we can feel the message he/she wants to convey more &quot;in our skin&quot; than if we were reading a book.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In other words, I think it happens more often in movies that we realize by being shown than we realize by thinking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&apos;s why I couldn&apos;t help but nod my head when I heard critic Lee Dong-jin&apos;s sentence, &quot;Movies make us hot&quot;. Not completely, but in my own sense of the word, movies are more intuitive because they &quot;show&quot; us something. It shows us the outcome before we&apos;ve even had a chance to think about it. So you could say that movies are passive in a way. And we &quot;feel&quot; the happiness or sadness of what we see in the movie. That&apos;s why movies are more intensely sensual and close to our hearts. Because the audiovisual information of the movie is transmitted directly to us.
Now, don&apos;t get me wrong. Hot doesn&apos;t mean bad.&lt;/p&gt;
&lt;p&gt;The heat that movies generate can even keep us alive. The warmth we get from the coldness of reality can give us the strength to stand up and face it again. So we need some heat in our lives. Movies can play this role.
However, as critic Lee Dong-jin said, &quot;Reason is basically cold&quot;. If you watch a movie that impresses you and you don&apos;t think about it for a period of time, you may easily forget it or not fully accept its message. This is because the &quot;hotness&quot; of a movie will eventually dissipate. In order for the temperature from the movie to affect the rational mind, it has to go through a kind of &quot;transformation process&quot;. This &quot;process of transformation&quot; will be a process that we will continue to reflect on within ourselves and translate into our own language.
From this point of view, books are the opposite of movies. Books don&apos;t &quot;show&quot; us, they make us &quot;think&quot; through the written word.&lt;/p&gt;
&lt;p&gt;In this process, the book implies a &quot;process of transformation&quot; that the movie must undergo. As we read, we organize the world of the book and interpret the information in it in our own language.
That&apos;s why I could sympathize with critic Lee Dong-jin when he said, &quot;As far as the liberal arts are concerned, movies will never be able to keep up with books.&quot; Because of their limitations, movies inevitably interfere with our rational thinking. Of course, some movies come to mind without thinking.
It&apos;s not the rational mind at work, but something else. In conclusion, we should use both books and movies appropriately in our lives. We should use movies to fuel our lives and books to nourish us through the problems we face. All in all, the cold reality is not solved by heat alone. We need to allocate them appropriately to solve the problems in our lives, because only through careful and strategic organization can we solve the problems in our lives.&lt;/p&gt;
</content:encoded><category>Lee Dong-jin</category><category>books and movies</category><author>Jinmu Go</author></item><item><title>Plan to attend CES 2026</title><link>https://jinmugo.com/en/posts/ces-2026-planning/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/ces-2026-planning/</guid><description>A planning note that groups the AI, smart home, and digital health companies and Innovation Award products to see at CES 2026, then maps an on-site route.</description><pubDate>Tue, 09 Dec 2025 11:27:34 GMT</pubDate><content:encoded>&lt;h2&gt;Category&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AI / Enterprise&lt;/li&gt;
&lt;li&gt;Smart Cities / IoT&lt;/li&gt;
&lt;li&gt;Cloud Computing&lt;/li&gt;
&lt;li&gt;Smart Home &amp;amp; Appliances&lt;/li&gt;
&lt;li&gt;Fashion tech&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;List of companies of interest&lt;/h2&gt;
&lt;h3&gt;AI&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/noonchee-vx-platform/&quot;&gt;Noonchee-VX Platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Smart Home&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/pila-mesh-home-battery/&quot;&gt;Pila Mesh Home Battery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/touchhl-ai-house-platform/&quot;&gt;touchHL AI house platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/somanest-mattress/&quot;&gt;SomaNest Mattress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/acoustic-eye/&quot;&gt;Acoustic Eye&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/balance-ai-rejuvenation-shower-system/&quot;&gt;BALANCE AI Rejuvenation Shower System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/balance-medi-water-ai/&quot;&gt;BALANCE Medi Water AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/glomensio-firefly-gen-3/&quot;&gt;Glomensio Firefly Gen 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/heymirror-smart-dressing-mirror/&quot;&gt;HEYMIRROR Smart Dressing Mirror&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/mova-mobius-60/&quot;&gt;MOVA MOBIUS 60&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Fashion tech&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/littlebird-safety-tracker/&quot;&gt;Littlebird Safety Tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Food tech&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/gardyn-studio-2/&quot;&gt;Gardyn Studio 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Digital health&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/bi-o-biohacking-lens/&quot;&gt;bi-O Biohacking Lens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/pf-sweat-patch-non-invasive-continuous-lactate-sensor/&quot;&gt;PF-Sweat Patch: Non-invasive &amp;amp; Continuous Lactate Sensor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/tsense/&quot;&gt;tSense&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Vehicle tech &amp;amp; advanced mobility&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/ai-transformer-home-trailer-ai-tht/&quot;&gt;AI Transformer Home Trailer (AI-THt)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Home Appliances&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/allcom-smart-tumbler-precise-baby-formula-control/&quot;&gt;Allcom Smart Tumbler - Precise Baby Formula Control&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/nitrogen-coffee-machine/&quot;&gt;Nitrogen Coffee Machine&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Computer hardware &amp;amp; components&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/anker-prime-charger-160w-3-ports-smart-display/&quot;&gt;Anker Prime Charger (160W, 3 Ports, Smart Display)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Computer peripherals &amp;amp; accessories&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/wizpr-ring/&quot;&gt;Wizpr Ring&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Edtech&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/chalk-mastering-concept-faster-through-visual-llm/&quot;&gt;CHALK: Mastering Concept Faster through Visual LLM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/mentorlens-ai-tutor-glass-supporting-personalized-studies-for-everyone/&quot;&gt;MentorLens - AI Tutor Glass Supporting Personalized Studies for Everyone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;headphones &amp;amp; personal audio&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;harman&lt;/li&gt;
&lt;li&gt;shokz&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/perisphere-audio-meets-vision/&quot;&gt;Perisphere: Audio Meets Vision&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;sports &amp;amp; fitness&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/orphe-insole/&quot;&gt;ORPHE INSOLE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;mobile devices, accessories &amp;amp; apps&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/otterbox-symmetry-series-cactus-leather-embroidery/&quot;&gt;OtterBox Symmetry Series Cactus Leather Embroidery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ces.tech/ces-innovation-awards/2026/seeru/&quot;&gt;SEERU&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Plan your visit&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Course&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;January 6th, 2019 Morning&lt;/td&gt;
&lt;td&gt;[LVCC North C5 Entrance] &amp;gt; Samsung SDS(N110) &amp;gt; N1 Entrance &amp;gt; Deepmind Platform (8353) &amp;gt; Hitachi (8529) &amp;gt; Primech AI (8935) &amp;gt; Segway-Ninebot (9615) &amp;gt; Abaka AI (9647) &amp;gt; PARADISE BRIDGE &amp;gt; [LVCC West Level 3] &amp;gt; Mobileye (W326) &amp;gt; Hyundai Mobis (W319) &amp;gt; [LVCC West Level 2]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;January 6th, 2019, Noon&lt;/td&gt;
&lt;td&gt;[Venetian Level 2 Hall A] &amp;gt; Innovation Awards Showcase (50043) &amp;gt; swisstech Pavilion (51239) &amp;gt; TP-Link Systems Inc. (51923) &amp;gt; WYBOTIC Co.,Ltd (51455) &amp;gt; SmartWings Home LLC (51762) &amp;gt; SwitchBot. Inc (52655) &amp;gt; ORPHE, Inc (54199) &amp;gt; Chamelo (56142)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;January 7 AM&lt;/td&gt;
&lt;td&gt;[Venetian Level 2 Hall A] &amp;gt; Innovation Awards Showcase (50043) &amp;gt; swisstech Pavilion (51239) &amp;gt; TP-Link Systems Inc. (51923) &amp;gt; WYBOTIC Co.,Ltd (51455) &amp;gt; SmartWings Home LLC (51762) &amp;gt; SwitchBot. Inc (52655) &amp;gt; ORPHE, Inc (54199) &amp;gt; Chamelo (56142)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;January 7th, 2020&lt;/td&gt;
&lt;td&gt;[Venetian Level 1 Hall G] &amp;gt; Canon U.S.A, Inc,&apos;s Business Innovation Group (60509) &amp;gt; Hyundai Motor and Kia ZER01NE-CRADLE (61311) &amp;gt; Samsung Electronics Co, Ltd. (C-Lab) (61511) &amp;gt; Industrial Bank of Korea (62949) &amp;gt; XbotPark (62919) &amp;gt; HongKong Tech (63200) &amp;gt; Korea Institute of Startup &amp;amp; Entrepreneurship Dev (62817) &amp;gt; Postech (61453) &amp;gt; Remarkable (61053) &amp;gt; LG NOVA Zenith Electronics LLC (60301)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;January 8, 2019, 8:00 a.m.&lt;/td&gt;
&lt;td&gt;[LVCC Central Hall C1 Entrance] &amp;gt; LG Electronics (15004) &amp;gt; Shokz (15823) &amp;gt; Bosch (16203) &amp;gt; Sony Honda Mobility Inc. (20800) &amp;gt; Tuya Global Inc. (16838) &amp;gt; South Hall Connector &amp;gt; [LVCC South Hall 1 &amp;amp; 2] (Self-guided tour if time permits)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded><category>CES</category><author>Jinmu Go</author></item><item><title>DHCP with wi-fi</title><link>https://jinmugo.com/en/posts/dhcp-with-wifi/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/dhcp-with-wifi/</guid><description>How a device receives an IP address and network configuration through the DHCP DORA process after Wi-Fi authentication and association.</description><pubDate>Sun, 21 Sep 2025 10:07:21 GMT</pubDate><content:encoded>&lt;p&gt;Wifi is now an inseparable part of our lives. Recently, I was taking a DHCP class in a networking class and suddenly I was using wifi every day, and I was curious about how it works and how to connect to it. In this article, I will try to summarize the basics of Wi-Fi and DHCP.&lt;/p&gt;
&lt;h2&gt;Wi-Fi&lt;/h2&gt;
&lt;p&gt;In a nutshell, an access point converts wired internet signals into wireless signals and scatters them around, and devices such as smartphones and laptops receive them to access the internet. Unlike a wired LAN (local area network), there are no physical cables to send and receive data through radio waves in the air.&lt;/p&gt;
&lt;p&gt;In other words, it&apos;s essentially the same as a regular wired internet connection in terms of how you access the internet and use services like surfing the web or watching videos. Wi-Fi simply replaces the last leg of the internet connection with radio waves instead of physical wires.&lt;/p&gt;
&lt;p&gt;However, the &quot;wireless&quot; difference makes some important differences, both technically and in the real world.
For example, reliability and speed. Wired connections are very reliable and fast because data travels over a physical cable. Wi-Fi, on the other hand, uses radio waves and is highly dependent on the surrounding environment. However, it&apos;s very mobile. In fact, this is probably its biggest raison d&apos;être and advantage: while wired internet can only be used in a fixed location, Wi-Fi gives you the convenience of being able to move around and use the internet as long as you have signal coverage.&lt;/p&gt;
&lt;p&gt;Except in peer-to-peer settings like hotspots, Wi-Fi works primarily on a client-server model. Generally speaking, based on the Wi-Fi environment we use, the roles are divided as follows&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server: Your router acts as a server. It allows and manages access to the network for each device and relays data.&lt;/li&gt;
&lt;li&gt;Clients: All devices that connect to the router to request and receive internet service, such as smartphones, laptops, smart TVs, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similar to the traditional client-server model, the client requests the server to connect to the Internet, and the server receives the request and connects to the Internet. DHCP is used to assign a network address (IP) so that the server can actually use the Internet in response to the client&apos;s request.&lt;/p&gt;
&lt;h3&gt;Relationship between Wi-Fi and DHCP&lt;/h3&gt;
&lt;p&gt;We mentioned that DHCP is used to assign IP addresses. The first thing we do when we connect to Wi-Fi in a cafe is to enter a password, but what does this have to do with DHCP?&lt;/p&gt;
&lt;p&gt;The answer is that the password authentication process happens before DHCP. Before the client requests an IP address from the DHCP server, it verifies that it is authorized to access the network. The overall flow looks like this&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scan: Your smartphone searches for available Wi-Fi signals around you. This is the familiar list we see on the Wi-Fi settings screen.&lt;/li&gt;
&lt;li&gt;Authentication: The user selects a specific Wi-Fi (SSID) and enters a password. The router verifies that the password is correct and that the person is authorized to access the network. This is the process we often think of as &quot;connecting to Wi-Fi.&quot; 3.&lt;/li&gt;
&lt;li&gt;Association: If the authentication is successful, the router will add the device to its managed list.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Only after the association phase is successful is the smartphone ready to send a DHCP Discover message to the network to get an IP address.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note] SSID
SSID stands for Service Set Identifier, which is the name of your wireless network (Wi-Fi network). It is a unique name that a router or access point (AP) assigns to identify the network it provides. For example, the name of the network that appears in the list of nearby Wi-Fi on your phone or laptop is the SSID. SSIDs serve as identifiers to distinguish between networks and prevent confusion when there are multiple networks in the same area.&lt;/p&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;DHCP&lt;/h2&gt;
&lt;p&gt;Short for Dynamic Host Configuration Protocol. It is a protocol that automatically (dynamically) assigns and manages information required for communication, including IP addresses, to devices connecting to a network.&lt;/p&gt;
&lt;p&gt;Imagine a cafe with Wi-Fi, where dozens or hundreds of customers access the Wi-Fi every day with a variety of devices. If you think about it for a moment, you can imagine the following problems that could arise without DHCP&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Problems with manual IP settings: What if each customer has to enter their own IP address? You don&apos;t know which IPs are free, and duplicate IPs can cause conflicts.&lt;/li&gt;
&lt;li&gt;Management complexity: If a cafe owner has to manage and record the IPs of all devices, it&apos;s not practical.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DHCP solves these problems. When a device joins the network, it automatically finds and assigns an available IP address, and when it&apos;s finished using it, it can be reclaimed and reassigned to another device.&lt;/p&gt;
&lt;h3&gt;DHCP in action (DORA)&lt;/h3&gt;
&lt;p&gt;Let&apos;s take a look at the four steps of DHCP that actually happen when you connect to Wi-Fi. This process is sometimes referred to as DORA, which is an acronym for each step to make it easier to remember.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Actual data transfer&lt;/p&gt;
&lt;p&gt;**1. D - Discover&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the client &lt;strong&gt;connects to the network&lt;/strong&gt;, it sends a broadcast message asking &quot;Is there a DHCP server?&quot;&lt;/li&gt;
&lt;li&gt;At this point, the client does not yet have an IP address, so we send it as a broadcast (255.255.255.255)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**2. O - Offer (Offer)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DHCP server (223.1.2.5) replies &quot;I&apos;m a DHCP server! Here are some IP addresses available&quot;&lt;/li&gt;
&lt;li&gt;The server offers network setup information, including available &lt;strong&gt;IP addresses&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**3. R - Request&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client says &quot;Okay. &lt;strong&gt;I&apos;d like to use this IP address!&quot;&lt;/strong&gt; and the server responds by broadcasting it&lt;/li&gt;
&lt;li&gt;If there are multiple DHCP servers, the client is notified that a specific server&apos;s proposal has been selected&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;**4. A - ACK (Acknowledge)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DHCP server confirms, &quot;Okay, now use that IP address!&quot;&lt;/li&gt;
&lt;li&gt;At this point, the client will be able to use the assigned IP address and network settings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the typical DHCP connection process. But there are a few questions you may have.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DHCP is used to assign IPs to nodes (to connect to the Internet). But how can a client connect to the network and send broadcast messages?&lt;/li&gt;
&lt;li&gt;Why is a request process necessary when a connection can be established by 1. discovering, 2. making an offer, and then the server 3. ACKing (just like the 3-way handshake in TCP)?&lt;/li&gt;
&lt;li&gt;Is there an expiration date for IP addresses? What happens if I leave the cafe and come back tomorrow?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I had these questions, so I looked it up.&lt;/p&gt;
&lt;h3&gt;1. How can I connect to the network and broadcast if I don&apos;t have an IP?&lt;/h3&gt;
&lt;p&gt;I thought that a network connection meant a connection at the Network Layer or higher, which is the third of the seven OSI layers that allows Internet communication by receiving an IP address.
However, DHCP Discover messages are only possible with a Data Link Layer connection, which is the second layer.&lt;/p&gt;
&lt;p&gt;The point of DHCP is for a client without an IP address to find a DHCP server on the network that it doesn&apos;t recognize. To do this, it needs to broadcast messages throughout the network that it knows about. TCP is not well suited for DHCP because it is oriented toward 1:1 connections and does not have broadcast capabilities.&lt;/p&gt;
&lt;p&gt;*TCP can&apos;t even be used by nodes that don&apos;t know their IP in the first place.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To summarize, DHCP&apos;s broadcasting is possible because it occurs at the second layer of communication, rather than at the third layer (network layer), where IP addresses are required.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. Why Request is required in the order of Discover -&amp;gt; Offer -&amp;gt; ACK&lt;/h3&gt;
&lt;p&gt;The main reason why the Request phase is necessary in DHCP is because there can be more than one DHCP server on the network.&lt;/p&gt;
&lt;p&gt;As you can see above, a client sends out a broadcast message on the network it belongs to. All DHCP servers on the network receive this message.
If there is only one server, this could be done in the order Discover -&amp;gt; Offer -&amp;gt; ACK (as is the case with TCP).
If there is more than one server, the client will receive multiple Offer messages with different IP addresses. The client has to choose one of these offers, which it does by &lt;strong&gt;broadcasting&lt;/strong&gt; the Request message back to the network, e.g., &quot;I&apos;m going to use the 192.168.0 IP address offered by server A&quot;.
The reason for this broadcast is for other servers that were not selected. The unselected servers realize that the client did not select their offer, and they &lt;strong&gt;reclaim&lt;/strong&gt; the IP address they offered so that they can assign it to another client. This is more efficient because it frees up space for other clients.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
Without the Request phase, a client would have no way to tell other servers which server&apos;s offer it accepted, nor would it be able to communicate which DHCP server to choose. The Request phase is essential to efficiently manage IP addresses by selecting one of several DHCP servers and notifying other unselected servers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3. IP address expiration date&lt;/h3&gt;
&lt;p&gt;IP addresses are a finite resource, and if a device leaves the network and continues to occupy an IP, the resource is depleted. In high-traffic areas such as cafes, devices are constantly changing, so it is important to reclaim unused IPs and reassign them to new devices.&lt;/p&gt;
&lt;p&gt;When a DHCP server assigns an IP address, it gives it a lease term: &quot;This IP is valid for N hours&quot;.  The client can only use that IP for this period of time, and must request a renewal from the server before it expires.&lt;/p&gt;
&lt;h3&gt;What if I leave and return to the DHCP server after being assigned an IP?&lt;/h3&gt;
&lt;p&gt;In this case, the behavior depends on whether the IP lease has expired or not.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;If the lease hasn&apos;t expired (e.g., you left and came back for a while)&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The client (my smartphone) remembers the IP address it was previously assigned.&lt;/li&gt;
&lt;li&gt;When it rejoins the network, it sends a direct &lt;code&gt;Request&lt;/code&gt; message to the DHCP server saying &quot;Can I continue using the IP address I was using last time?&quot; without going through the whole DORA process.&lt;/li&gt;
&lt;li&gt;If the server says yes, you get a &lt;strong&gt;ACK&lt;/strong&gt;, and you&apos;re assigned an IP and connected faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**When the lease expires (for example, if you come back the next day)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The IP address that my smartphone had has expired, so the IP may have been reclaimed by the DHCP server and is being used by someone else.&lt;/li&gt;
&lt;li&gt;Since my smartphone does not have a valid IP, it will go through the entire DORA 4-step process again, starting with Discover, just like the first time it connected.&lt;/li&gt;
&lt;li&gt;You may get your old IP back, but in most cases, you will be assigned a new IP address from another available one.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Finalize&lt;/h2&gt;
&lt;p&gt;So far, we&apos;ve learned about Wi-Fi and DHCP. Let&apos;s recap.
Let&apos;s say you&apos;re in a cafe and you want to connect to Wi-Fi to view Instagram,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Scan:&lt;/strong&gt; Your smartphone detects the &quot;Cafe_WiFi&quot; signal.&lt;/li&gt;
&lt;li&gt;tap &quot;Cafe_WiFi&quot; and enter your password. The cafe router verifies that the password is correct.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Association:&lt;/strong&gt; The router will add your smartphone to its management list. You can now send and receive data to and from the router.&lt;/li&gt;
&lt;li&gt;Start DHCP (DORA):**
&lt;ul&gt;
&lt;li&gt;Discover (D):** The smartphone sends a Discover request that is broadcast throughout the network.&lt;/li&gt;
&lt;li&gt;The routers (DHCP servers) hear the message and respond.&lt;/li&gt;
&lt;li&gt;R (Request): The smartphone accepts the offer and broadcasts it again so that other servers know.&lt;/li&gt;
&lt;li&gt;A (ACK): The router finally acknowledges and finalizes the IP assignment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Internet Communication Starts:&lt;/strong&gt; Your smartphone now has a unique address and can send and receive data to and from the Instagram servers through the router.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Behind the scenes of my casual Wi-Fi connection, all these different levels of promises were working organically in a very short time. I hope this article has helped you understand how Wi-Fi and DHCP work.&lt;/p&gt;
&lt;p&gt;*Please note that this is a personal study and compilation, so there may be inaccuracies and gaps. Please leave a comment!&lt;/p&gt;
</content:encoded><category>DHCP</category><category>Wi-fi</category><author>Jinmu Go</author></item><item><title>Domain Name System (DNS) DeepDive - Background and Systems</title><link>https://jinmugo.com/en/posts/dns-deepdive-1/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/dns-deepdive-1/</guid><description>How the limits of centrally managed HOSTS.TXT led to hierarchical, delegated DNS and its distributed domain-name management model.</description><pubDate>Sun, 08 Jun 2025 12:58:28 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;The Internet is for Everyone&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;I was browsing the Internet one day and was curious about the behavior of the Domain Name System (DNS). Not only was I curious about why DNS was created, but I was also curious about how it manages the different domains (.com, .net, .kr) that are out there today. I came across a book called The &lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=282893007&amp;amp;partner=openAPI&amp;amp;start=api&quot;&gt;DNS Practical Textbook&lt;/a&gt;, and I&apos;m going to write a series of blogs based on it.&lt;/p&gt;
&lt;h2&gt;IP addresses and names&lt;/h2&gt;
&lt;p&gt;There are tons of computers, smartphones, routers, and more connected around the world that are called &quot;servers&quot; that provide information or services to other computers. These networked computers are called &lt;strong&gt;hosts&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;With so many computers connected, when hosts communicate with each other, they need to somehow specify who they are communicating with. Conversely, if the other host doesn&apos;t know who is communicating with them, it&apos;s hard for them to determine if they should or shouldn&apos;t allow the communication.&lt;/p&gt;
&lt;p&gt;The Internet uses Internet Protocol (IP) addresses to do this. An IP address is an address used to identify someone to communicate with.&lt;/p&gt;
&lt;p&gt;However, IP addresses are hard to memorize and easy to get wrong because they are a list of numbers, and they change from time to time due to administrative reasons. If you specify an old IP address without realizing it&apos;s changed, you might be connected to a completely different party.&lt;/p&gt;
&lt;p&gt;To solve this problem, we came up with an easy-to-memorize and easy-to-use way to specify who you want to communicate with by &lt;strong&gt;name&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note] Addressing and naming.
Specifying who you want to communicate with, the sender or receiver, by an address according to a set of rules is called &lt;strong&gt;addressing&lt;/strong&gt;, and giving a name to the person or service you want to communicate with and mapping it to an address is called &lt;strong&gt;naming&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Manage the mapping of IP addresses to names&lt;/h2&gt;
&lt;p&gt;As described in the previous chapter, the Internet uses IP addresses to identify people on the Internet, but it&apos;s easier to use names when you&apos;re actually specifying who you want to communicate with. We&apos;ve organized the correspondence between names and IP addresses into a table so that when you&apos;re specifying who you want to communicate with, you can just look up the IP address that corresponds to the name and not have to memorize the IP address.&lt;/p&gt;
&lt;p&gt;In the early days of the Internet, this was accomplished by maintaining a text file called `HOSTS.TXT&apos; that listed the IP addresses and name correspondences of all hosts connected to the Internet.&lt;/p&gt;
&lt;p&gt;Because IP addresses must be unique across the Internet, it&apos;s important to keep track of which devices are using which IP addresses, so the &lt;code&gt;HOSTS&lt;/code&gt; file is maintained by the Stanford Research Institute Network Information Center (SRI-NIC) to ensure that no names or numbers are duplicated. An organization that maintains a list of commonly used names or numbers across the Internet is called a registry.&lt;/p&gt;
&lt;p&gt;At the time, organizations that wanted to connect to the Internet would apply to SRI-NIC, which would check and review each application, assign addresses, and register the results in the &lt;code&gt;HOSTS&lt;/code&gt; file. The &lt;code&gt;HOSTS&lt;/code&gt; file would then be made publicly available on the Internet, and users would download and use the file.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;From centralized to decentralized management&lt;/h2&gt;
&lt;p&gt;As the Internet evolved, the number of hosts wanting to connect to it increased the volume of applications for SRI-NICs, which gradually slowed down the process. It was clear that the growing number of organizations wanting to connect to the Internet would strain the management structure.&lt;/p&gt;
&lt;p&gt;This is where the idea of a distributed management structure with layering and delegation came from.&lt;/p&gt;
&lt;h3&gt;Tiering and delegation&lt;/h3&gt;
&lt;p&gt;The tiering and delegation mindset is used to manage large organizations like companies.
Companies create departments based on the type of work they do, and define the roles of each department to clarify the organizational structure. This is called &quot;hierarchy.&quot; Then, they assign department heads to each department, and delegate management to them. This is delegation.
The modern Internet uses this structure of layering and delegation to manage the IP addresses and names of hosts.&lt;/p&gt;
&lt;p&gt;The Internet shares one space, called a &lt;strong&gt;name space&lt;/strong&gt;, across the board, so the structure was adopted to carve up parts of the name space and delegate the carved up name space to other trusted parties. &lt;strong&gt;The delegating party only manages the information about who they delegated that name space to&lt;/strong&gt;, and the delegated party is responsible for managing that name space.&lt;/p&gt;
&lt;p&gt;Introducing tiering and delegation has two advantages.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;it reduces the burden on each administrator by decentralizing management.&lt;/li&gt;
&lt;li&gt;it gives you the flexibility to respond to organizational growth and change.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This means that if the scope of management grows and becomes unmanageable, you can simply divide it up as needed and delegate it to new admins.
But what about duplication if this layering and delegation means that each administrator has a &lt;code&gt;HOSTS&lt;/code&gt; file? As mentioned above, in the early days of the Internet, SRI-NICs were centralized so that there were no duplicate names or numbers.&lt;/p&gt;
&lt;p&gt;To ensure that this advantage was not lost when we moved to a decentralized management scheme, it was designed as a tree structure with a single vertex. In a tree structure, you can ensure that your namespace is unique by managing duplicate names at each level of the tree as branches branch out.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!caution] What to watch out for with tiering and delegation
While the benefits of introducing layering and delegation are great, the only way to achieve this decentralized management is to ensure that the organizations responsible for each layer are well managed and accountable for their portions.
For example, it is possible to attack the DNS by intentionally and maliciously setting inappropriate settings for domain names such as &lt;a href=&quot;https://www.paloaltonetworks.co.kr/cyberpedia/what-is-an-nxnsattack&quot;&gt;NXNSAttack&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Configuration of domain names&lt;/h2&gt;
&lt;p&gt;On the Internet, the scope of each partitioned namespace is called a &lt;strong&gt;domain&lt;/strong&gt;, and the name given to identify that scope is called a &lt;strong&gt;domain name&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;What is a domain name?&lt;/h3&gt;
&lt;p&gt;By organizing the names at each layer into a tree with no duplicates, domain names become unique on the internet. And by properly mapping these domain names to IP addresses, domain names can be used as an &lt;strong&gt;identifier&lt;/strong&gt; to identify internet hosts.&lt;/p&gt;
&lt;p&gt;For example, the &lt;code&gt;jinmu.me&lt;/code&gt; part of &lt;code&gt;https://jinmu.me&lt;/code&gt; is the &lt;code&gt;domain name&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Organization of a domain name&lt;/h3&gt;
&lt;p&gt;A domain name is made up of strings of characters concatenated with &apos;.(dot)&apos;. Each string is called a &lt;strong&gt;label&lt;/strong&gt;. Actually, there is also a dot (.) at the end of the domain name, which is usually omitted. The dot at the end of a domain name represents the &lt;strong&gt;root&lt;/strong&gt;, which is the apex of the hierarchy, and is called, in order from right to left, from the root, as follows&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TLD (Top Level Domain)&lt;/li&gt;
&lt;li&gt;2nd Level Domain (2LD)&lt;/li&gt;
&lt;li&gt;3rd Level Domain (3LD)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;subdomain&lt;/h3&gt;
&lt;p&gt;When the scope of one namespace falls within the scope of another namespace, it is called a &lt;strong&gt;subdomain&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Subdomains can be created freely by the administrator of that domain, and they can decide whether or not to delegate the subdomains they create to others.&lt;/p&gt;
&lt;h2&gt;DNS created to use the domain name&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;DNS&lt;/strong&gt; is short for Domain Name System. As a system developed under the premise of the introduction of domain names, DNS also adopts a decentralized management structure based on layering and delegation.&lt;/p&gt;
&lt;p&gt;DNS manages the correspondence between domain names and IP addresses and finds the IP address that corresponds to a domain name at the request of a user. This is known as name resolution.&lt;/p&gt;
&lt;p&gt;The primary goal of DNS is to follow the hierarchy of domain names, obtaining the necessary information from the administrators at each level, to reach its final goal: an IP address.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;The structure of DNS layering and delegation&lt;/h3&gt;
&lt;p&gt;DNS hierarchizes scopes of management in a way that corresponds to domain names, and distributes management by delegation. The scope of management made possible by delegation is called a zone. In DNS, the person who delegates (the delegator) and the person who is delegated to (the delegatee) have a parent-child relationship.&lt;/p&gt;
&lt;p&gt;To delegate a zone, you first create a subdomain, which is created by the delegator. For example, if you create a subdomain under me and delegate it to someone else, you create a parent-child relationship where me is the parent and the delegate from me is the child. The administrator of each zone manages the information with a server called a name server.&lt;/p&gt;
&lt;p&gt;There are two types of information managed by the name server, as shown below.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;domain names and IP addresses of hosts in the zone.
&lt;ul&gt;
&lt;li&gt;The name servers in each zone manage the mapping of domain names to IP addresses.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;delegation information
&lt;ul&gt;
&lt;li&gt;This is the name server information of the delegate (child), which is managed by the name server of the delegator (parent).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Relationship between DNS and the registry&lt;/h3&gt;
&lt;p&gt;As described in &lt;a href=&quot;#managing-the-mapping-of-ip-addresses-to-names&quot;&gt;Managing the mapping of IP addresses to names&lt;/a&gt;, management by the &lt;code&gt;HOSTS&lt;/code&gt; file is a simple form of centralized management of names or numbers by a single registry (SRI-NIC). The introduction of domain names and DNS has reduced the burden on administrators and allowed for more flexible management, but it also means that there are now multiple registries managing names.&lt;/p&gt;
&lt;p&gt;This hierarchy introduced by domain names and DNS requires an administrator (registry) to manage each layer. Each registry has two responsibilities&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;manage the zones they have been entrusted with (delegated).&lt;/li&gt;
&lt;li&gt;if it delegates a zone, it manages who the zone is delegated to (the delegate).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For domain names and DNS as decentralized names to work smoothly as a whole, the registries that manage each zone and their stakeholders must be aligned and cooperative.&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;We&apos;ve seen why DNS was created, how it works, and how it is managed globally and distributed through layering and delegation. The evolution from a simple text file managing `HOSTS&apos; to the sophisticated and scalable DNS system we have today is a testament to the growth of the Internet.&lt;/p&gt;
&lt;p&gt;DNS isn&apos;t just a tool that turns domain names into IP addresses; it&apos;s the backbone of the Internet, allowing devices around the world to communicate seamlessly. The design philosophy of hierarchy and delegation, in particular, has allowed this vast system to operate flexibly and reliably. At the end of the day, for DNS to work well, it&apos;s important that the administrators at each layer do their job and work together. In this way, DNS is more than just a technology, it&apos;s a social commitment and a collaborative system.&lt;/p&gt;
&lt;p&gt;In the next article, we&apos;ll take a deeper dive into registries, exploring the registry and registrar model, and the registration and use of domain names.&lt;/p&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=282893007&amp;amp;partner=openAPI&amp;amp;start=api&quot;&gt;DNS Practical Textbook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>DNS</category><category>NameServer</category><author>Jinmu Go</author></item><item><title>Domain Name System (DNS) DeepDive - Registry, Registrar</title><link>https://jinmugo.com/en/posts/dns-deepdive-2/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/dns-deepdive-2/</guid><description>The roles and operating models of domain registries and registrars, plus how name-server delegation works.</description><pubDate>Sat, 28 Jun 2025 11:46:25 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;The Internet is for Everyone&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;In the last article, we learned about the background and system of DNS and domain names. In this article, we&apos;re going to learn about domain names and the registration and management structure that keeps DNS running smoothly.&lt;/p&gt;
&lt;h2&gt;What is a registry?&lt;/h2&gt;
&lt;p&gt;The Internet is built on decentralized management, with no single entity centralizing the entire Internet.
The exception to this is identifiers like IP addresses and domain names to identify hosts connected to the Internet, which require centralized management. The organization that does this is called a &lt;strong&gt;registry&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note] Registries and registry operators
The term &quot;registry&quot; is used in two senses.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a registry operator that assigns identifiers and manages registrations.&lt;/li&gt;
&lt;li&gt;a registry database, which is the register handled by a registry operator.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;In this article, the &quot;registry operator&quot; in 1. is referred to as the registry.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Differences in management between IP addresses and domain names&lt;/h3&gt;
&lt;p&gt;IP addresses and domain names are handled differently for allocation and registration management due to their respective characteristics.
Because IP addresses share a finite resource across the Internet, they need to be managed &lt;strong&gt;consistently&lt;/strong&gt; on a global scale.
To accomplish this, IP address registries are responsible for setting rules or coordinating between registries.
Domain names, on the other hand, have a single namespace that is partitioned across TLDs, and &lt;strong&gt;have the flexibility to operate according to the specifics of each TLD&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;The role of registries&lt;/h3&gt;
&lt;p&gt;In order to use a domain name, you must apply to a registry for registration. The registry then reviews and verifies that the application meets the registration requirements and registers it in its database.&lt;/p&gt;
&lt;p&gt;The main roles of registries are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;manage the operation of the registry database
&lt;ul&gt;
&lt;li&gt;It operates a registry database that stores information such as names of individuals, organizations, and contact information required to register a domain name.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Establishing registration rules in accordance with policy
&lt;ul&gt;
&lt;li&gt;The registry establishes the &lt;strong&gt;policy&lt;/strong&gt; of the domain names it registers and manages, and establishes &lt;strong&gt;registration rules&lt;/strong&gt; to realize the policy and notifies users.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Receiving registration applications
&lt;ul&gt;
&lt;li&gt;The registry receives applications for registration of domain names from registrants. It examines the applied domain names according to the rules and registers the information received in the registry database.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Provide Whois services
&lt;ul&gt;
&lt;li&gt;The registry provides information on domain names it manages as a &lt;code&gt;Whois&lt;/code&gt; service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Operate nameservers
&lt;ul&gt;
&lt;li&gt;Manages and operates &lt;strong&gt;Nameservers&lt;/strong&gt; to make the domains it manages available on the Internet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Relationship between registries and TLDs&lt;/h3&gt;
&lt;p&gt;A registry exists for each Top Level Domain (TLD), and it manages each registry TLD and establishes management policies or registration rules.&lt;/p&gt;
&lt;p&gt;There are two main types of TLDs.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Country Code Top Level Domain (ccTLD), a domain assigned to each country or region.
&lt;ul&gt;
&lt;li&gt;ex) &lt;code&gt;.kr&lt;/code&gt;, &lt;code&gt;.jp&lt;/code&gt;, &lt;code&gt;.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Generic Top Level Domain (gTLD), a domain that is independent of country or region.
&lt;ul&gt;
&lt;li&gt;ex) &lt;code&gt;.com&lt;/code&gt;, &lt;code&gt;.net&lt;/code&gt;, &lt;code&gt;.org&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Registries and the Registrar Model and the Role of Registrars&lt;/h2&gt;
&lt;p&gt;In order to use a domain name, it must be registered in the registry database of the registry that manages it.&lt;/p&gt;
&lt;p&gt;Today, the major TLDs (.com/.net/.kr) use the &lt;strong&gt;registry⋅registrar model&lt;/strong&gt; as their registration structure.&lt;/p&gt;
&lt;h3&gt;Registry⋅registrar model&lt;/h3&gt;
&lt;p&gt;The registry⋅registrar model separates the management of domain name registrations into two roles, as follows&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The reason for this separation of roles is to ensure that the names of the domains being registered are unique, while allowing for diversity in pricing and services. This is why there is only one registry but multiple registrars for a single TLD.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Each registrar can offer different services to registrants. Registrars can set their own services and pricing, and registrants can choose the registrar that&apos;s right for them.&lt;/p&gt;
&lt;p&gt;In Korea, Gabia and HostingKR are examples of registrar services.&lt;/p&gt;
&lt;h3&gt;Role of a registrar&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Receive registration applications from registrants&lt;/li&gt;
&lt;li&gt;Request registration in the registry database&lt;/li&gt;
&lt;li&gt;providing WHOIS services&lt;/li&gt;
&lt;li&gt;managing registrant information&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Registering domain names&lt;/h2&gt;
&lt;p&gt;Let&apos;s take a look at the flow of registering a domain name in the registry⋅registrar model.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Applicant&lt;/strong&gt; checks through the &lt;code&gt;whois&lt;/code&gt; service if the domain name is available for registration and selects a provider to apply for the domain name. They compare prices and services and choose the one they like. Next, they prepare the information they need to submit to the &lt;strong&gt;registrar&lt;/strong&gt;.
Once this is done, they apply to the registrar to register the domain name.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;registrar&lt;/strong&gt; will verify your application and submit it to the &lt;strong&gt;registry&lt;/strong&gt; for registration in the registry database.&lt;/p&gt;
&lt;p&gt;The registry verifies that the application received from the registrar is valid and, if it meets the registration requirements, registers the information in its database. It then notifies the registrar that the registration is complete. Upon receiving the notification, the registrar notifies the user that the domain name is now registered.&lt;/p&gt;
&lt;h2&gt;Using your domain name&lt;/h2&gt;
&lt;p&gt;Above, the user has registered a domain name. However, just registering a domain name doesn&apos;t make it usable. To make the website with the domain name accessible with a web browser, some preparation is required.&lt;/p&gt;
&lt;p&gt;First, you need to register a &lt;strong&gt;name server&lt;/strong&gt; that manages the information to make that domain name available on the internet, known as DNS information. You can build your own name server or use an external service like cloudflare. The name server must also be accessible from anywhere on the internet.&lt;/p&gt;
&lt;p&gt;Second, set the information for your domain name on the name server you initially set up. For example, if your registered domain name is &lt;code&gt;jinmu.me&lt;/code&gt;, set the information that &lt;code&gt;jinmu.me&lt;/code&gt; has an IP address of &lt;code&gt;76.76.21.21&lt;/code&gt; on the name server.&lt;/p&gt;
&lt;p&gt;The final step is to make sure that the name server can answer questions from the Internet based on the information you&apos;ve registered. For example, it should be able to answer the question, &quot;What is the IP address of &lt;code&gt;jinmu.me&lt;/code&gt;?&quot; with the answer &lt;code&gt;76.76.21.21&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;What the registry does&lt;/h3&gt;
&lt;p&gt;The registry registers name server information in the registry database and sets that information on the name servers it manages. It sets the name server information that contains the information for &lt;code&gt;jinmu.me&lt;/code&gt; to the name servers in the ME zone that the registry manages. The parent (me) sets the name server information of the child (jinmu.me), and the relationship between the registry and the registrant becomes a parent-child relationship as described in DNS.&lt;/p&gt;
&lt;p&gt;After completing the above procedure, you can actually build a web server and see if you can actually access a website with that domain name (jinmu.me).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;In this article, we took a closer look at the registration and management structures that are necessary for domain names to function smoothly. From the role of the registry in centralizing and managing Internet identifiers to the function of the registrar in brokering domain registrations for users, we saw how the registry-registrar model, which is adopted by most TLDs today, enables reliable management of domain names and competition in service and price, and how the actual domain registration process works. Lastly, we also pointed out that there&apos;s more to it than just registering a domain - you need to set up a name server and have it registered with its parent domain before it can be used on the internet.&lt;/p&gt;
&lt;p&gt;In the next post, we&apos;ll discuss how our computers resolve domain names once they&apos;re registered and set up, a process called DNS name resolution, and why delegation is a key principle in making this huge system work smoothly.&lt;/p&gt;
&lt;p&gt;Thank you.&lt;/p&gt;
</content:encoded><category>DNS</category><category>Registry</category><category>Registrar</category><author>Jinmu Go</author></item><item><title>Domain Name System (DNS) DeepDive - Name Resolution</title><link>https://jinmugo.com/en/posts/dns-deepdive-3/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/dns-deepdive-3/</guid><description>How DNS queries follow hierarchical name servers, how recursive and iterative queries differ, and how caching reduces load and latency.</description><pubDate>Sun, 06 Jul 2025 02:48:10 GMT</pubDate><content:encoded>&lt;p&gt;Finding the IP address that corresponds to a domain name according to the user&apos;s needs is called name resolution. In this post, we will see the basic behavior of name resolution by DNS.&lt;/p&gt;
&lt;h2&gt;Query and answer&lt;/h2&gt;
&lt;p&gt;The basis of Name Resolution is a query and a response. This query and response has three promises.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;queries and responses always correspond 1:1.
&lt;ul&gt;
&lt;li&gt;You will never get a response that doesn&apos;t correspond to a query, or two responses to a query.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you want to know information, you must specify the domain name and type of information you want to know.
&lt;ul&gt;
&lt;li&gt;The name and type must be specified together, such as &quot;IP address of jinmu.me&quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The person providing the information responds to the query with the information they know.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Name Resolution follows a hierarchical structure&lt;/h2&gt;
&lt;p&gt;As we discussed in the previous post, DNS uses hierarchy and delegation to create a hierarchy with the root as the vertex. The basis of name resolution by DNS is to follow the order of the hierarchy, starting with the root name server at the top, and query it to get the information you want to know, and end up with the IP address you need. This behavior is called iterative resolution in DNS, and we&apos;ll refer to it as following the hierarchy.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In order for a querier to follow the hierarchy of DNS and perform name resolution, they need to know the appropriate query source. This is why DNS has adopted a structure where a child registers its name server information with its parent, and the parent, upon receiving a query for a delegated domain name, responds with the child&apos;s name server information as the next query source. This structure allows the querier to follow the hierarchy by delegation.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Preparation (left side of the figure).&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;A parent-child relationship is established between &lt;code&gt;root&lt;/code&gt; and &lt;code&gt;me&lt;/code&gt; by delegation. Root is the parent and me is the child.&lt;/li&gt;
&lt;li&gt;me registers its name server information with root, the parent. Root registers and configures the name server information registered by me to its name servers.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Real name resolution (right side of the figure)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;while the parent-child relationship is established by delegation, A asks Root, &quot;Please tell me the IP address of jinmu.me&quot;.&lt;/li&gt;
&lt;li&gt;the root responds with the name server information of &lt;code&gt;me&lt;/code&gt; (&lt;code&gt;b.dns.me&lt;/code&gt;) because it only knows the name server information of the delegate for &lt;code&gt;me&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A queries &lt;code&gt;b.dns.me&lt;/code&gt; using the name server information for me that it received from root.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Following the DNS hierarchy in this way, starting at the root and working backward, is the basis of the name resolution structure.&lt;/p&gt;
&lt;h2&gt;Name resolution in action&lt;/h2&gt;
&lt;p&gt;Let&apos;s take a look at the hierarchical name resolution we saw above in a little more detail.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;query
&lt;ul&gt;
&lt;li&gt;The user sends a query to the name server at the top of the hierarchy, the root, specifying the name and kind of information they want to know.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;response
&lt;ul&gt;
&lt;li&gt;The root responds with the name server information of &lt;code&gt;me&lt;/code&gt; (&lt;code&gt;b.dns.me&lt;/code&gt; in this example) because it is delegating to &lt;code&gt;me&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;query
&lt;ul&gt;
&lt;li&gt;From the response received from root, we can see two things
&lt;ul&gt;
&lt;li&gt;Root is delegating &lt;code&gt;me&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The delegate&apos;s name server is &lt;code&gt;b.dns.me&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use this information to send a single query to the name server for &lt;code&gt;me&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Response
&lt;ul&gt;
&lt;li&gt;Because &lt;code&gt;me&lt;/code&gt; is delegating to &lt;code&gt;jinmu.me&lt;/code&gt;, it responds with the name server information of its delegate, &lt;code&gt;jinmu.me&lt;/code&gt; (&lt;code&gt;ns1.jinmu.me&lt;/code&gt; in this example).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query
&lt;ul&gt;
&lt;li&gt;From the response received from &lt;code&gt;me&lt;/code&gt;, we can see two things
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;me&lt;/code&gt; is delegating &lt;code&gt;jinmu.me&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The name server of the delegate is &lt;code&gt;ns1.jinmu.me&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using this information, send the same query as in step 1 to the name server at &lt;code&gt;jinmu.me&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Response
&lt;ul&gt;
&lt;li&gt;The name server of &lt;code&gt;jinmu.me&lt;/code&gt; responds with the IP address because it knows the IP address of &lt;code&gt;jinmu.me&lt;/code&gt;. This allows the user to get the IP address of &lt;code&gt;jinmu.me&lt;/code&gt; (&lt;code&gt;76.76.21.21&lt;/code&gt;) and the name resolution ends.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Reducing the load and time of name resolution&lt;/h2&gt;
&lt;p&gt;While it is certainly possible to perform name resolution by following the DNS hierarchy from the root, it requires a lot of requests, responses, and time. Therefore, a solution was devised to have a separate server in charge of name resolution and accept requests from other hosts to perform name resolution on their behalf.&lt;/p&gt;
&lt;p&gt;In our example, let&apos;s call this agent X. You send a request to X: &quot;&lt;strong&gt;Please resolve names for me&lt;/strong&gt; and give me the IP address of `jinmu.me**&quot;, and X will do the name resolution described above.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;X responds to User with the IP address &lt;code&gt;76.76.21.21&lt;/code&gt; of &lt;code&gt;jinmu.me&lt;/code&gt; by performing the name resolution requested by A.&lt;/p&gt;
&lt;p&gt;When X resolves a name, it stores the information from the querying name server for some time. If A makes the same query to X within that time, X already has the result, so it doesn&apos;t resolve a new name and responds to the user with the result it already has.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This reduces the number of queries to the name servers, which reduces the load and time it takes to resolve names.&lt;/p&gt;
&lt;p&gt;From the information so far, we can see that there are three different roles when it comes to DNS name resolution.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the person who needs the information (User A, User B, User C)&lt;/li&gt;
&lt;li&gt;a person (X) who is doing the name resolution on behalf of the person who needs the information.&lt;/li&gt;
&lt;li&gt;those who provide the information (the name servers that create the hierarchy of DNS)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;In this article, we looked at &quot;name resolution,&quot; the process of finding the IP address corresponding to a domain name. We learned about the basic principle of &quot;iterative resolution,&quot; which starts from the root name server and follows the hierarchy in order, and the emergence of name resolvers with cache to reduce the query and response load and time of this process. We saw that the DNS ecosystem consists of three roles: &quot;users&quot; who request information, &quot;cache resolvers&quot; who execute name resolution on behalf of users, and &quot;authoritative name servers&quot; who provide information.&lt;/p&gt;
&lt;p&gt;So far, we&apos;ve painted the big picture of &quot;how&quot; DNS works. In our next post, we&apos;ll take it a step further and dive deeper into the specific components of DNS that actually make this process possible, and what information they pass back and forth to each other.&lt;/p&gt;
&lt;p&gt;Acknowledgments.&lt;/p&gt;
</content:encoded><category>DNS</category><author>Jinmu Go</author></item><item><title>Finished my first 15 kilometers!</title><link>https://jinmugo.com/en/posts/first-15km-running/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/first-15km-running/</guid><description>The first step toward a full marathon.</description><pubDate>Sun, 27 Apr 2025 10:39:58 GMT</pubDate><content:encoded>&lt;p&gt;I went out for an easy 5 kilometers, but the weather was nice and the podcast I was listening to was interesting, so I ran more.
My legs got stiff as I went on, but I thought I could run a half marathon.
&lt;/p&gt;
&lt;p&gt;Thanks to these podcasts for keeping me from getting bored while running!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://podcasts.apple.com/kr/podcast/ep57-4%EC%9B%94%EC%9D%98-%EB%B0%9C%EA%B2%AC-%EC%98%A4%EB%9E%98-%EB%8B%A4%EC%A0%95%ED%95%98%EB%A0%A4%EB%A9%B4-%EA%B0%80%EB%81%94-%EB%B3%84%EB%A1%9C%EC%97%AC%EC%95%BC-%ED%95%B4/id1738806607?i=1000705022558&amp;amp;l=en-GB&quot;&gt;무소속 생활자 57화&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://podcasts.apple.com/kr/podcast/%EA%B9%80%ED%98%9C%EB%A6%AC%EC%9D%98-%ED%95%84%EB%A6%84%ED%81%B4%EB%9F%BD/id1188513056?i=1000617803118&quot;&gt;필름클럽 186화&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>marathon</category><author>Jinmu Go</author></item><item><title>2025 Chuncheon Marathon completes its first full marathon</title><link>https://jinmugo.com/en/posts/first-full-marathon/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/first-full-marathon/</guid><description>I thought I was going to die.</description><pubDate>Mon, 27 Oct 2025 05:32:08 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I completed the full course of the 2025 Chuncheon Marathon. I&apos;ve been running consistently for a long time, so I thought it would be relatively easy, but the last 40-42 kilometers felt farther than ever.&lt;/p&gt;
&lt;p&gt;I had only run up to 32 kilometers in practice and participated in the marathon, so the 10-kilometer section from 32 to 42 kilometers was an unknown section, but I was glad to see that I ran stably. I think it was probably better because I had a pacer for the first 20 kilometers.&lt;/p&gt;
&lt;p&gt;The scenery was beautiful and the pace was perfect for a fall marathon. I got up in the morning, taped my knee and arrived about an hour before the start to warm up. There were so many people that it was hard to move around, but the excitement of the marathon made me feel excited.&lt;/p&gt;
&lt;p&gt;After running the full marathon, a lot of people asked me why I did it, and I don&apos;t really know. I don&apos;t know about you, but I think I just run, and I think that&apos;s a stronger motivator than any other reason. If you run, you run...&lt;/p&gt;
&lt;p&gt;And thanks to Chimgukji for keeping me from getting bored while running...&lt;/p&gt;
&lt;p&gt;Additionally
The medal was so beautiful.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
</content:encoded><category>marathon</category><category>running</category><author>Jinmu Go</author></item><item><title>An Introduction to Split Keyboards</title><link>https://jinmugo.com/en/posts/first-split-keyboard/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/first-split-keyboard/</guid><description>A two-week review of the Corne v4.1 split keyboard, covering shoulder strain, portability, layer adaptation, wireless connectivity trade-offs, and my keymap.</description><pubDate>Sun, 27 Jul 2025 11:13:28 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been coding a lot lately, and my shoulders have been stiff from sitting and typing for a long time. I remembered hearing about split keyboards a couple of years ago when I was really into keyboards, and decided to give it a try.&lt;/p&gt;
&lt;p&gt;I&apos;d heard that split keyboards are less comfortable to type on than regular keyboards, but I&apos;m more of a convenience person than a comfort person, so I figured it was worth a try.&lt;/p&gt;
&lt;p&gt;The domestic market for split keyboards is not very large, so the options are limited, and they are quite expensive to buy in Korea. In the end, I had to look overseas.&lt;/p&gt;
&lt;p&gt;As with other keyboards, there were two ways to buy a split keyboard: buy the parts and assemble it yourself, or buy the finished product. I chose the finished product because I wanted to try it out quickly and figure out my preferences. The Chinese market is the most developed in this area, so I bought it through Taobao.&lt;/p&gt;
&lt;p&gt;My criteria for choosing a split keyboard were as follows&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;portability: it should be compact enough to be carried around&lt;/li&gt;
&lt;li&gt;minimalist layout: The fewer keys, the better&lt;/li&gt;
&lt;li&gt;connectivity: both wired and wireless, but preferably wireless&lt;/li&gt;
&lt;li&gt;decorative elements: no LEDs, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since I wanted to use it on the go, I was looking for a keyboard that met the above criteria, even if it was difficult to get used to at first.
After searching around the internet, I realized that a lot of people were buying Corne v4.1 as an entry-level keyboard, so I chose this model. I think it&apos;s a good choice that fulfills my requirements and is affordable.&lt;/p&gt;
&lt;p&gt;I&apos;ve been using it for about two weeks now. The first few days were definitely a learning curve, but I&apos;m pretty happy with it now. My experience so far has been good/bad.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Improved shoulder stiffness:** First of all, my main reason for purchasing this product was to improve my shoulder stiffness. I was able to keep my hands in their natural position, which reduced a lot of tension in my shoulders and arms.&lt;/li&gt;
&lt;li&gt;Portability:** It&apos;s small and lightweight, so it&apos;s easy to carry in my bag. I can easily take it to cafes and other places to work.&lt;/li&gt;
&lt;li&gt;Utilizes desk space: It takes up much less space than a traditional keyboard. I especially like the fact that you can spread the sides as far apart as you want.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cons&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Difficult to type special characters: It&apos;s still awkward to type special characters compared to a regular keyboard. There are a lot of characters that require you to switch between layers, which I&apos;m still not completely used to.&lt;/li&gt;
&lt;li&gt;Unreliable wireless connection: The wireless connection sometimes drops out. You can use it wired, but I&apos;m not willing to give up the convenience of wireless.&lt;/li&gt;
&lt;li&gt;Noise issues: The typing noise is louder than I expected.  I&apos;ve ordered a silent switch to replace it, but I&apos;m not sure if it&apos;s because of the small size of the airplane.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Overall&lt;/h2&gt;
&lt;p&gt;After two weeks of use, I am very pleased overall. The initial goal of improving shoulder stiffness is definitely working, and the portability and space utilization have exceeded my expectations.&lt;/p&gt;
&lt;p&gt;There are a few inconveniences, but they&apos;re mostly manageable with adaptation, and I&apos;m satisfied enough that I have no intention of buying another keyboard at this point.&lt;/p&gt;
&lt;p&gt;If you&apos;re on the fence about a split keyboard, it&apos;s definitely worth a try, especially if you have shoulder or wrist discomfort.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Keymap&lt;/h2&gt;
&lt;p&gt;I&apos;m attaching the keymap I&apos;m using now, in case it helps.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;GitHub - JinmuGo/zmk-config-corner&quot;
image: &quot;https://opengraph.githubassets.com/9d321906a805d9c45f9c7ec68bacef10b51c149ae108081c5a19f65e1afd0f97/JinmuGo/zmk-config-corne&quot;
description: &quot;Contribute to JinmuGo/zmk-config-corne development by creating an account on GitHub.&quot;
url: &quot;https://github.com/JinmuGo/zmk-config-corne?tab=readme-ov-file&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can find a slightly more recent keymap in this repo.&lt;/p&gt;
</content:encoded><category>keyboard</category><category>splitKeyboard</category><author>Jinmu Go</author></item><item><title>The Difference Between Git Squash and Fixup: When to Use Each</title><link>https://jinmugo.com/en/posts/git-squash-vs-fixup/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/git-squash-vs-fixup/</guid><description>`squash` merges commit messages into a single commit, while `fixup` discards the messages of the commits being merged. We&apos;ll also explain a safe cleanup workflow using `--fixup` and `--autosquash`.</description><pubDate>Fri, 11 Jul 2025 01:13:41 GMT</pubDate><content:encoded>&lt;p&gt;Both merge the current commit into a previous commit, but the difference lies in &lt;strong&gt;how commit messages are handled&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;squash&lt;/code&gt;: Combines the messages of the two commits into a single message, which you can then edit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fixup&lt;/code&gt;: Discards the message of the fixing commit and preserves the message of the target commit as-is.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re adding a typo or an omission to a commit whose description is already complete, &lt;code&gt;fixup&lt;/code&gt; is the right choice. If you need to rewrite the meaning of multiple commits into a single commit, use &lt;code&gt;squash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;squash&lt;/h2&gt;
&lt;p&gt;Commits changed to &lt;code&gt;squash&lt;/code&gt; or &lt;code&gt;s&lt;/code&gt; in the interactive rebase list are merged into the commit immediately above them.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pick   9ecdf8 refactor: tmux config
squash 8d5218 refactor: cleanup zsh config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Git opens the commit messages to be merged in an editor. This is useful when the final commit needs to describe both actions or when you want to rewrite the message.&lt;/p&gt;
&lt;p&gt;You can also create a squash commit by specifying a target commit in advance.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git commit --squash=&amp;lt;target-commit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This commit has the &lt;code&gt;squash!&lt;/code&gt; prefix, and &lt;code&gt;--autosquash&lt;/code&gt;—which will be explained later—moves it to the target location.&lt;/p&gt;
&lt;h2&gt;fixup&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;fixup&lt;/code&gt; or &lt;code&gt;f&lt;/code&gt; also merges the changes into the commit immediately above it. The default &lt;code&gt;fixup&lt;/code&gt; discards the squash commit’s message, so you don’t need to reopen the message editor.&lt;/p&gt;
&lt;p&gt;Let’s say I discovered an omission in the lazygit configuration commit &lt;code&gt;3f05b2a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;After staging the modified files, create a commit using Git’s &lt;code&gt;--fixup&lt;/code&gt; option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add lazygit/
git commit --fixup=3f05b2a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Git automatically generates an accurate title, such as &lt;code&gt;fixup! feat: add lazygit config&lt;/code&gt;. While you can type the prefix manually, it’s easy to make mistakes if the target title changes or if there are similar commits, so it’s safer to use &lt;code&gt;git commit --fixup=&amp;lt;commit&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Squashing to the Target’s Location with &lt;code&gt;autosquash&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;A fixup commit is created on the HEAD you’re working on and may be located away from the target. &lt;code&gt;--autosquash&lt;/code&gt; finds &lt;code&gt;fixup!&lt;/code&gt;, &lt;code&gt;squash!&lt;/code&gt;, and &lt;code&gt;amend!&lt;/code&gt; commits, moves them immediately after the target, and adjusts the rebase action accordingly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rebase -i --autosquash &amp;lt;base&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Specify the commit immediately preceding the range to be squashed in &lt;code&gt;&amp;lt;base&amp;gt;&lt;/code&gt;. To squash starting from the target in the example, you can run the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rebase -i --autosquash 3f05b2a^
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Once you review and save the list, the squashed changes will be merged into the target commit, and the &lt;code&gt;fixup!&lt;/code&gt; commit will be removed.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you don’t want to enter the option every time, you can use Git’s default settings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global rebase.autoSquash true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even after setting this, you can still manually verify the order before saving the list from &lt;code&gt;git rebase -i &amp;lt;base&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;When You Want to Edit the Message Too&lt;/h2&gt;
&lt;p&gt;The latest versions of Git support message rewriting even within the fixup family.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --fixup=&amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge changes while preserving the existing target message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --fixup=amend:&amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Squashes changes while preserving the target message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --fixup=reword:&amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Squashes changes while rewriting only the target message&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;amend:&lt;/code&gt; and &lt;code&gt;reword:&lt;/code&gt; create an &lt;code&gt;amend!&lt;/code&gt; commit, and when rebasing with &lt;code&gt;--autosquash&lt;/code&gt;, that message is used as the new message for the target commit. For simple corrections, the default &lt;code&gt;--fixup&lt;/code&gt; is sufficient.&lt;/p&gt;
&lt;h2&gt;Comparison at a Glance&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;&lt;code&gt;squash&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;fixup&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Changes&lt;/td&gt;
&lt;td&gt;Merged into a previous commit&lt;/td&gt;
&lt;td&gt;Merged into a previous commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt;Combine and edit multiple messages&lt;/td&gt;
&lt;td&gt;Discard the amended message and retain the target message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Main Purpose&lt;/td&gt;
&lt;td&gt;Rewrite the meaning of multiple changes into a single commit&lt;/td&gt;
&lt;td&gt;Address minor omissions, typos, or review feedback in an existing commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quick Creation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git commit --squash=&amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git commit --fixup=&amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Safe Usage Scenarios&lt;/h2&gt;
&lt;p&gt;Rebase generates new commit IDs. It is safest to perform this on a local branch that has not yet been shared.&lt;/p&gt;
&lt;p&gt;If you absolutely must fix a personal branch that has already been pushed to the remote, coordinate with your team members first, and after testing, use the following command instead of the standard &lt;code&gt;--force&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git push --force-with-lease
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even &lt;code&gt;--force-with-lease&lt;/code&gt; does not resolve conflicts if someone else is working on the same branch. It’s best to avoid rewriting the public history of shared branches and the default branch.&lt;/p&gt;
&lt;p&gt;The workflow I use most often is short.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git commit --fixup=&amp;lt;target&amp;gt;
git rebase -i --autosquash &amp;lt;base&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While working, immediately record improvements as &lt;code&gt;fixup&lt;/code&gt; commits, and then consolidate them all at once before review. This allows you to create a readable history without the hassle of repeatedly editing commit messages.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-commit&quot;&gt;Official git commit documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-rebase&quot;&gt;Official git rebase documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>git</category><author>Jinmu Go</author></item><item><title>Why Did HTTP/1.1 Pipelining Disappear?</title><link>https://jinmugo.com/en/posts/http-pipelining/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/http-pipelining/</guid><description>This article explains how HTTP/1.1 pipelining reduces RTT, the HOL blocking caused by response ordering, and how HTTP/2 and HTTP/3 have improved upon this.</description><pubDate>Thu, 16 Oct 2025 13:08:17 GMT</pubDate><content:encoded>&lt;p&gt;HTTP/1.1 pipelining is a &lt;strong&gt;feature that reduces RTT waste by sending multiple requests consecutively over the same connection without waiting for the previous response&lt;/strong&gt;. However, since the server had to send responses in the order they were received, this led to application-layer Head-of-Line (HOL) blocking, where a delay in the first response would block subsequent, faster responses. Due to this limitation and the difficulty of error recovery, it was not widely adopted, and HTTP/2’s stream multiplexing took its place.&lt;/p&gt;
&lt;h2&gt;HTTP/1.0: By Default, a New Connection for Each Request&lt;/h2&gt;
&lt;p&gt;The default model in HTTP/1.0 is non-persistent connections. For each resource request—such as HTML, CSS, or images—a TCP connection is established, the response is received, and the connection is closed.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since the TCP handshake and slow-start overhead are repeated with every request, latency increases significantly on pages with many resources. At the time, some implementations reused connections using the &lt;code&gt;Keep-Alive&lt;/code&gt; extension, but this was not the default behavior of HTTP/1.0.&lt;/p&gt;
&lt;h2&gt;HTTP/1.1: Connection Reuse Doesn’t Eliminate Wait Times&lt;/h2&gt;
&lt;p&gt;HTTP/1.1 uses persistent connections by default unless explicitly terminated. Since a single TCP connection is reused for multiple requests, the cost of establishing a connection is reduced.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;However, this does not automatically eliminate the wait time between requests. If you send one request, wait until the response is fully received, and then send the next request, the connection remains idle between each round trip.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RTT (Round Trip Time) is the time it takes for a request to travel to the destination and for the response to return. It is used not only to describe the establishment of a TCP connection but also to explain the latency of HTTP requests and responses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;How Pipelining Works&lt;/h2&gt;
&lt;p&gt;With pipelining, the client sends subsequent requests over the same connection without waiting for the first response.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The client establishes a persistent TCP connection.&lt;/li&gt;
&lt;li&gt;The client sends requests 1, 2, and 3 consecutively without waiting for a response.&lt;/li&gt;
&lt;li&gt;The server processes the multiple requests.&lt;/li&gt;
&lt;li&gt;The server sends responses 1, 2, and 3 &lt;strong&gt;in the same order as the requests&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since multiple requests can be squeezed into a single round trip, the theoretical benefit is significant in high-latency environments. However, it is not accurate to simplify the rules regarding methods into a single sentence such as “only idempotent methods are allowed.”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The server can process requests for safe methods in parallel.&lt;/li&gt;
&lt;li&gt;Whether the client can automatically retry if the connection is interrupted depends on idempotency.&lt;/li&gt;
&lt;li&gt;As a general rule, after sending a non-idempotent request, the client should not pipeline additional requests until it receives the final response. Therefore, while POST is not unconditionally prohibited at the protocol level, it must be handled conservatively because recovery is difficult.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;HOL Blocking Caused by Response Order&lt;/h2&gt;
&lt;p&gt;HTTP/1.1 messages lack a stream identifier that would allow responses to be sent out of order and reassembled. Consequently, even if the server processes requests in parallel, it must send responses in the order they were received.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. GET /api/complex-report  → 5 seconds
2. GET /images/logo.png     → 10 ms
3. GET /styles.css → 10 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even if the results for requests 2 and 3 are ready first, they cannot be transmitted until the response for request 1 is complete. This phenomenon, where the head of the queue blocks items behind it, is known as HOL (Head-of-Line) blocking in HTTP/1.1 pipelining.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It was difficult for browsers and intermediate proxies to implement pipelining consistently, and they also had to determine which requests to safely resend after a connection failure. In practice, opening multiple TCP connections in parallel proved more predictable, and pipelining never became mainstream.&lt;/p&gt;
&lt;h2&gt;What Did HTTP/2 and HTTP/3 Change?&lt;/h2&gt;
&lt;p&gt;HTTP/2 divides requests and responses into frames within a single connection and distinguishes them using stream IDs. Even if one stream is slow, response frames from other streams can be sent first, thereby eliminating &lt;strong&gt;HTTP/1.1’s application-layer HOL blocking&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;However, all streams share a single TCP connection. If a single TCP packet is lost, the streams on that connection may all have to wait together until that packet is retransmitted. This is &lt;strong&gt;transport-layer HOL blocking&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;HTTP/3 uses QUIC instead of TCP and isolates the transmission state for each stream, reducing the problem where packet loss in one stream blocks other streams.&lt;/p&gt;
&lt;p&gt;In summary, the idea of pipelining itself—overlapping multiple tasks without leaving a single connection idle—was correct. The flaw lay in HTTP/1.1’s message structure, which required responses to be sent in order; later versions removed this constraint through stream identification and multiplexing.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9112.html&quot;&gt;RFC 9112: HTTP/1.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9113.html&quot;&gt;RFC 9113: HTTP/2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9114.html&quot;&gt;RFC 9114: HTTP/3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>http</category><category>pipelining</category><category>keep-alive</category><category>tcp</category><category>rtt</category><category>HOL</category><author>Jinmu Go</author></item><item><title>Configuring Storybook Composition in a Monorepo</title><link>https://jinmugo.com/en/posts/monorepo-storybook-composition/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/monorepo-storybook-composition/</guid><description>How to run Storybook for a Next.js app and UI packages independently while consolidating them into a single Composition hub using refs, wait-on, and Chromatic permalinks.</description><pubDate>Tue, 13 May 2025 13:02:43 GMT</pubDate><content:encoded>&lt;p&gt;If you want to view your Next.js app and the Storybook for your UI package in one place even after separating them in a monorepo, you can &lt;strong&gt;run each Storybook independently and link them via the &lt;code&gt;refs&lt;/code&gt; in the central Storybook&lt;/strong&gt;. This is called Storybook Composition.&lt;/p&gt;
&lt;p&gt;However, Composition isn’t always necessary. Since Storybook currently offers a framework specifically for Next.js, it’s simpler to include UI package stories in a single Next.js Storybook instance for small projects that share the same dependencies and deployment cycles. I chose Composition because I needed to separate the configuration, ownership, and deployment of the UI package from the web app.&lt;/p&gt;
&lt;h2&gt;Structure Used&lt;/h2&gt;
&lt;p&gt;Initially, I was only displaying components from &lt;code&gt;packages/ui&lt;/code&gt; in the shared Storybook. When I imported the &lt;code&gt;apps/web&lt;/code&gt; code as-is to verify the service page composition and Provider state, dependencies from the Next.js environment and the web app spilled over into the shared Storybook.&lt;/p&gt;
&lt;p&gt;So I divided the roles as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;monorepo/
├── apps/
│   ├── storybook/ # Composition host, :6006
│   └── web/
│ └── .storybook/     # Next.js app Storybook, :6008
└── packages/
    └── ui/
 └── .storybook/     # UI package Storybook, :6007
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;packages/ui&lt;/code&gt;: Reusable components and design system stories&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apps/web&lt;/code&gt;: Stories that depend on actual pages, layouts, and the app provider&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apps/storybook&lt;/code&gt;: A hub for exploring both Storybooks without loading component code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the Next.js app, we use the currently recommended &lt;code&gt;@storybook/nextjs-vite&lt;/code&gt;. It requires Next.js 14.1 or higher and Vite 5 or higher, and supports features such as &lt;code&gt;next/image&lt;/code&gt;, routing, &lt;code&gt;next/head&lt;/code&gt;, and fonts. The reason we chose Composition is not because Next.js cannot run in Storybook, but &lt;strong&gt;to isolate dependencies and configurations for each area&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Local Composition Configuration&lt;/h2&gt;
&lt;p&gt;Add &lt;code&gt;refs&lt;/code&gt; to the host file, &lt;code&gt;apps/storybook/.storybook/main.ts&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import type { StorybookConfig } from &quot;@storybook/react-vite&quot;

const config: StorybookConfig = {
  stories: [&quot;../src/README.mdx&quot;],
  framework: &quot;@storybook/react-vite&quot;,
  refs: (config, { configType }) =&amp;gt; {
    if (configType === &quot;DEVELOPMENT&quot;) {
 return {
 ui: {
 title: &quot;UI Development&quot;,
 url: &quot;http://localhost:6007&quot;,
 },
        web: {
 title: &quot;Web Development&quot;,
 url: &quot;http://localhost:6008&quot;,
 },
 }
    }

    return {
 ui: {
 title: &quot;UI&quot;,
 url: &quot;https://main--&amp;lt;ui-app-id&amp;gt;.chromatic.com&quot;,
 },
      web: {
 title: &quot;Web&quot;,
 url: &quot;https://main--&amp;lt;web-app-id&amp;gt;.chromatic.com&quot;,
 },
    }
  },
}

export default config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Port mappings must be consistent from start to finish.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Address&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Composition Host&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:6006&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI Package&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:6007&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js Web App&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:6008&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Storybook reads the &lt;code&gt;index.json&lt;/code&gt; file at the reference URL to display the list of stories in the navigation panel. Therefore, &lt;code&gt;http://localhost:6007/index.json&lt;/code&gt; and &lt;code&gt;http://localhost:6008/index.json&lt;/code&gt; must be open in the browser. Since the frames in the Storybook are loaded directly by the user’s browser, if they use an internal address or require authentication, the viewer must have the necessary access permissions.&lt;/p&gt;
&lt;h2&gt;Safely Running the Three Storybooks in Order&lt;/h2&gt;
&lt;p&gt;You can launch each Storybook in a separate terminal.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Terminal 1
pnpm --filter ./packages/ui storybook -- --port 6007

# Terminal 2
pnpm --filter ./apps/web storybook -- --port 6008

# Terminal 3
pnpm --filter ./apps/storybook storybook -- --port 6006
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you start all three tasks in parallel, as with Turborepo, the host may start up first. In this case, the reference server isn’t ready yet, so the &lt;code&gt;index.json&lt;/code&gt; request fails. You just need to wait until both metadata URLs return a 2xx status using &lt;code&gt;wait-on&lt;/code&gt;, which is already in use in the host package’s script.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;storybook&quot;: &quot;wait-on http-get://localhost:6007/index.json http-get://localhost:6008/index.json &amp;amp;&amp;amp; storybook dev -p 6006&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason for using &lt;code&gt;http-get://&lt;/code&gt; is not just to check if the port is open, but to actually send a GET request to &lt;code&gt;index.json&lt;/code&gt; and verify a successful response.&lt;/p&gt;
&lt;h3&gt;Distinguishing Between “CORS Errors” and Setup Failures&lt;/h3&gt;
&lt;p&gt;The first console message I saw was as follows.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wait-on&lt;/code&gt; resolves only &lt;strong&gt;startup race conditions&lt;/strong&gt;. If the browser still displays &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; or credentials errors even after the referenced server is fully up and running, this is an actual CORS configuration issue. In this case, you must fix the response headers or same-origin configuration of the proxy or hosting service providing the referenced Storybook. Increasing the wait time will not resolve this.&lt;/p&gt;
&lt;p&gt;Two steps are sufficient to verify this.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify that the reference Storybook’s &lt;code&gt;/index.json&lt;/code&gt; returns a 2xx status code and JSON data&lt;/li&gt;
&lt;li&gt;Open the host Storybook and confirm that the UI and Web items are displayed in the navigation panel&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Linking the Chromatic Deployment URL&lt;/h2&gt;
&lt;p&gt;Build the UI, Web, and Composition separately in the deployment environment as well. In the host’s &lt;code&gt;refs&lt;/code&gt;, we’ve included Chromatic’s branch permalink instead of a URL that changes with every build.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://&amp;lt;branch&amp;gt;--&amp;lt;appid&amp;gt;.chromatic.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, for the &lt;code&gt;main&lt;/code&gt; branch, the URL would be &lt;code&gt;https://main--&amp;lt;appid&amp;gt;.chromatic.com&lt;/code&gt;. Since this URL points to the latest build of that branch, you don’t need to change the host configuration every time.&lt;/p&gt;
&lt;p&gt;You should also verify the visibility settings. Even if the Composition host is public, unauthorized users cannot view the stories if the referenced Chromatic project is private.&lt;/p&gt;
&lt;h2&gt;When to Choose Composition&lt;/h2&gt;
&lt;p&gt;The separation costs associated with Composition were justified under the following conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The UI package and the app use different Storybook frameworks or configurations.&lt;/li&gt;
&lt;li&gt;Different teams own or deploy each area independently.&lt;/li&gt;
&lt;li&gt;The host must not have runtime dependencies on the referenced packages.&lt;/li&gt;
&lt;li&gt;You need to view Storybooks from multiple repositories or tech stacks in a single navigation panel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conversely, if the same team deploys on the same schedule and there aren’t many stories, a single Storybook is preferable. Since Composition is not a feature for merging code but rather &lt;strong&gt;a feature for grouping already executable Storybooks via URLs&lt;/strong&gt;, the build, hosting, and access permissions for the referenced Storybooks must still be managed separately.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://storybook.js.org/docs/sharing/storybook-composition&quot;&gt;Storybook Composition Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://storybook.js.org/docs/get-started/frameworks/nextjs-vite/?renderer=react&quot;&gt;Official Storybook for Next.js with Vite documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chromatic.com/docs/permalinks/&quot;&gt;Chromatic permalink documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jeffbski/wait-on&quot;&gt;wait-on repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://turborepo.com/docs/guides/tools/storybook&quot;&gt;Turborepo’s Storybook Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>storybook-composition</category><category>monorepo</category><category>storybook</category><category>nextjs</category><category>chromatic</category><author>Jinmu Go</author></item><item><title>Proxies, there&apos;s nowhere to hide!</title><link>https://jinmugo.com/en/posts/proxy-no-more-retreat/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/proxy-no-more-retreat/</guid><description>A practical overview of proxies—forward and reverse placement, how they receive traffic, routing uses, and trade-offs.</description><pubDate>Sat, 12 Jul 2025 06:31:40 GMT</pubDate><content:encoded>&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;I didn&apos;t answer the question about Reverse Proxy properly in my &lt;a href=&quot;https://ausg.me/&quot;&gt;Ausg&lt;/a&gt; 9th interview on July 12, so to celebrate (?), I thought I&apos;d take this opportunity to write a blog post about Proxy that I&apos;ve been procrastinating on.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
This post is based on a variety of sources, but especially on the Proxies chapter of the &lt;a href=&quot;https://dl.ebooksworld.ir/books/HTTP.The.Definitive.Guide.Brian.Totty.David.Gourley.OReilly.9781565925090.EBooksWorld.ir.pdf&quot;&gt;Http definitive guide&lt;/a&gt;. Also, I&apos;m limiting the proxies discussed here to Web Proxies that use the HTTP/HTTPS protocol.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Proxy&lt;/h2&gt;
&lt;p&gt;Proxy literally means &lt;strong&gt;&apos;agent&apos;&lt;/strong&gt; or &lt;strong&gt;&apos;intermediary&apos;&lt;/strong&gt;. In the world of the web, a proxy is an intermediary that sits between two entities, a client and a server, and represents HTTP communication between them. Because of the nature of being between the client and the server, a proxy has a dual nature: it is both a &lt;strong&gt;web server&lt;/strong&gt; that receives requests from the client and returns responses, and a &lt;strong&gt;web client&lt;/strong&gt; that sends requests to the server and receives responses.
A proxy isn&apos;t just a messenger that delivers messages; it&apos;s more like an all-powerful control tower that inspects all traffic passing through, guides it to the best route, and even rewrites the content.&lt;/p&gt;
&lt;h2&gt;Why Use Proxy?&lt;/h2&gt;
&lt;p&gt;We&apos;ve already compared proxies to an &quot;all-purpose control tower,&quot; so why do we need one? What value do they provide beyond simply delivering messages, and why are we willing to take on the complexity of the TCP/IP architecture to adopt them?&lt;/p&gt;
&lt;p&gt;Importantly, most of the features I&apos;m about to describe apply to both forward and reverse proxies, depending on the direction of the traffic.&lt;/p&gt;
&lt;h3&gt;Increased security&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Firewall: A proxy acts as a firewall at the perimeter of your network, managing traffic going out or coming in. It can be a &lt;strong&gt;single point of defense&lt;/strong&gt; to block certain kinds of malicious requests and protect your internal network.&lt;/li&gt;
&lt;li&gt;Access control and filtering: Preventing access to certain websites in a school or company is what proxies do. You can filter out inappropriate content, centrally manage access to specific resources, and keep a record of all access.&lt;/li&gt;
&lt;li&gt;Anonymization: Because proxies send requests to the server on behalf of the user, they can strip personally identifiable information such as the user&apos;s IP address, browser information, and cookies from the HTTP header or body to enhance privacy and anonymity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Performance optimization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Web Caching: One of the most powerful features of a proxy. By storing a copy of frequently requested content (e.g. logo, CSS file, etc.) on the proxy server, when the same request is made in the future, the cached data can be delivered immediately instead of going to the source server, which is far away, increasing speed and reducing traffic to the server.&lt;/li&gt;
&lt;li&gt;Load Balancing: Large services have multiple web servers running simultaneously. Proxies evenly distribute incoming requests across multiple servers, preventing any particular server from being overloaded and increasing the reliability and efficiency of the entire system.&lt;/li&gt;
&lt;li&gt;Server acceleration (reverse proxy): A proxy that sits directly in front of a web server and disguises itself as the web server is called a &lt;strong&gt;reverse proxy&lt;/strong&gt; or &lt;strong&gt;surrogate&lt;/strong&gt;. It handles heavy tasks like SSL encryption and static content caching, allowing the actual web server to focus on handling core business logic.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Content transformation and routing&lt;/h2&gt;
&lt;p&gt;Proxies can go beyond simple forwarding and can also &lt;strong&gt;transcode&lt;/strong&gt; content or &lt;strong&gt;route&lt;/strong&gt; it to different destinations on demand.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transcoding content: A proxy can change the format of content before delivering it to the client. For example, a high-quality image can be converted to a small JPEG file for mobile devices, or a complex webpage can be converted to simple text for delivery.&lt;/li&gt;
&lt;li&gt;Content routing: You can change the destination of traffic based on the content of the request, such as sending requests starting with &quot;/api&quot; to an application server, &quot;/video&quot; to a media streaming server, and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Where Do Proxies Go?&lt;/h2&gt;
&lt;p&gt;Proxies are deployed in various locations on your network to serve different purposes. Where a proxy is located and how it directs traffic determines its role and function. In other words, a proxy&apos;s location defines its role and function.&lt;/p&gt;
&lt;h3&gt;Different deployment locations for proxy servers&lt;/h3&gt;
&lt;p&gt;Proxies are strategically placed to control the flow of traffic.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Egress Proxy: Located at the &lt;strong&gt;exit&lt;/strong&gt; of the local network. They are primarily used by businesses or organizations to control the traffic that internal users send to the Internet. They are deployed to reduce internet bandwidth costs and for security purposes such as content filtering to prevent employees from accessing harmful sites and virus protection.&lt;/li&gt;
&lt;li&gt;Access / Ingress Proxy: Located at the &lt;strong&gt;access point&lt;/strong&gt; of your Internet Service Provider (ISP), it aggregates requests from a large number of customers. Its main purpose is to cache popular content to improve download speeds for users and reduce internet bandwidth costs.&lt;/li&gt;
&lt;li&gt;Surrogate / Reverse Proxy: It sits at the &lt;strong&gt;end of the network&lt;/strong&gt;, right in front of the web server. It acts as if it is the web server and receives all requests first. This greatly improves performance by reducing the load on the actual web server, either by defending against DDos attacks or by caching frequently requested content. A Content Delivery Network (CDN) is a prime example of a reverse proxy.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Proxy hierarchy&lt;/h3&gt;
&lt;p&gt;Proxies can stand alone, but they can also form a &quot;hierarchy&quot; of multiple proxies connected like a chain. A request message (HTTP Requeset) can travel through multiple proxies sequentially until it reaches its final destination, the origin server.
In this case, the next proxy in the request&apos;s path is called the &quot;parent&quot; and the previous proxy is called the &quot;child&quot;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note] Dynamic Routing
Rather than simply sending requests to a set parent, a proxy can dynamically forward requests to other proxies or servers based on various conditions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Below are some examples of Dynamic Routing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Load balancing: A child proxy can select a parent proxy to balance the load based on the current workload level of the parent proxy. There are different algorithms for load balancing, so you may want to look them up if you&apos;re curious.&lt;/li&gt;
&lt;li&gt;Geographic proximity routing: A child proxy can choose a parent proxy that serves the geographic region of the origin server.&lt;/li&gt;
&lt;li&gt;Protocol/type routing: Child proxies can route to different parent proxies and origin servers based on URIs; certain types of URIs may cause requests to be sent through a special proxy server for specialized protocol handling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;How Proxies Get Traffic&lt;/h2&gt;
&lt;p&gt;Since web browsers (ex: safari, google chrome, arc) typically communicate directly with web servers, you must first establish how HTTP traffic goes through the proxy. No matter how powerful a proxy is, it&apos;s useless if traffic just passes through it without going through the proxy. In order for a proxy to do its job, it must force web traffic from the client to go through the proxy. There are two main ways to direct this traffic: server-side control and client/network control.&lt;/p&gt;
&lt;p&gt;In this article, we&apos;re going to take a closer look at the server-side control method in particular.**&lt;/p&gt;
&lt;h3&gt;DNS modifications&lt;/h3&gt;
&lt;p&gt;This is the most common way for reverse proxies (or sirgates) to receive traffic. The &lt;strong&gt;core principle&lt;/strong&gt; is that the reverse proxy takes over the identity of the real web server.&lt;/p&gt;
&lt;p&gt;Here&apos;s how it works&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DNS record setup: When an administrator sets up DNS records for a website&apos;s hostname (e.g. jinmu.me), they register the reverse proxy&apos;s IP address instead of the real web server&apos;s IP address.&lt;/li&gt;
&lt;li&gt;Client&apos;s DNS lookup: When a user types jinmu.me in a browser, the client&apos;s computer asks the DNS server for the IP address of this domain.&lt;/li&gt;
&lt;li&gt;return the proxy IP address: The DNS server returns the IP address of the reverse proxy as set in the response.&lt;/li&gt;
&lt;li&gt;Send request to proxy: &lt;strong&gt;The client sends an HTTP request to that address, completely unaware that this IP address belongs to the proxy&lt;/strong&gt;. **To the client, the proxy is the jinmu.me web server itself.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&apos;re interested in learning more about the behavior of DNS, I highly recommend checking out my &lt;a href=&quot;/series&quot;&gt;DNS Series&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Thanks to this approach, the client doesn&apos;t need to know anything and the server architecture is free to change.&lt;/p&gt;
&lt;h3&gt;HTTP Redirection&lt;/h3&gt;
&lt;p&gt;Another way is for the web server to directly &quot;tell&quot; the client to use a proxy.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the client requests a resource from the web server.&lt;/li&gt;
&lt;li&gt;Instead of processing the request directly, the web server sends a response with a special HTTP status code of &lt;strong&gt;305 Use Proxy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The Location header in this response contains the address of the proxy server that the client should use.&lt;/li&gt;
&lt;li&gt;The client that receives this response should resend the same request through the proxy server specified in the Location header.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, this &lt;code&gt;305&lt;/code&gt; status code is &lt;strong&gt;now rarely used, and has been deprecated by many modern browsers for security reasons&lt;/strong&gt; because of the potential risk that a malicious server could be directed to a proxy that could spy on the user&apos;s traffic. So while it exists in concept, it is rarely seen in the real world.&lt;/p&gt;
&lt;h3&gt;Client and network-side control methods&lt;/h3&gt;
&lt;p&gt;This is the opposite, controlling traffic flow directly from the client, the origin of the traffic, or from the network, the intermediate path. It is mainly used by &lt;strong&gt;forward proxies&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Direct Route Setup (Client Settings): This is the most classic method. You can either go into your web browser settings and manually tell it to &quot;connect to the internet via this proxy server&quot;, or you can use a script (PAC file) with specific rules to dynamically decide whether to use a proxy based on the URL.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Network modification (transparent proxy): Unbeknownst to the client or user, &lt;strong&gt;network equipment (routers, switches) in the way cast an invisible net&lt;/strong&gt; and force HTTP traffic to the proxy server. It&apos;s also called a &quot;transparent proxy&quot; because it&apos;s invisible to the user.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Disadvantages&lt;/h2&gt;
&lt;p&gt;As powerful as proxies are, as with any technology, where there&apos;s light, there&apos;s shadow, and when we say &quot;he controls everything,&quot; we also mean &quot;everything depends on him.&quot; There are a few downsides to proxies that must be considered when introducing them into your architecture.&lt;/p&gt;
&lt;h3&gt;Single Point of Failure (SPOF)&lt;/h3&gt;
&lt;p&gt;This is the most fatal weakness of proxies. All traffic must go through the proxy, which means that if the proxy server goes down, the entire service can be paralyzed. This is why it&apos;s practically essential in production to have redundancy by having multiple proxy servers, or to use a service that guarantees its own high availability, such as a load balancer in a cloud environment.&lt;/p&gt;
&lt;h3&gt;Performance bottlenecks and complexity&lt;/h3&gt;
&lt;p&gt;Proxies add a very small amount of latency as they process and forward requests in the middle. In most cases, this is negligible, but if the proxy server is under-specified or its settings are not optimized, it can become a bottleneck that slows down the performance of the entire system. Additionally, proxy hierarchies or complex routing rules can add to the complexity of the architecture, making it very difficult to set up and manage.&lt;/p&gt;
&lt;h3&gt;Security and privacy concerns&lt;/h3&gt;
&lt;p&gt;Proxies introduced to enhance security can paradoxically become a security hole. With all of the traffic being concentrated, if the proxy server itself is hacked, the entire system is at risk. Especially if SSL/TLS traffic is decrypted (SSL Termination) to inspect the contents, the proxy has access to all of the unencrypted sensitive data. This puts a lot of responsibility on the administrator, and creates another challenge to ensure the security of the proxy server itself is tightly managed.&lt;/p&gt;
&lt;h2&gt;Outro&lt;/h2&gt;
&lt;p&gt;So, we started with the definition of a proxy, then moved on to why they are used, where they are found in various locations, how they control traffic, and finally the downsides.
This post started with the regret of not being able to answer the question about reverse proxy properly in my AUSG interview, but I was able to go beyond the superficial understanding of &quot;a reverse proxy is something you put in front of a web server&quot; and understand why it needs to be there and how it works so that the client is communicating with the proxy without realizing it. I&apos;m reminded that the process of researching and refining my writing is the surest way to learn.&lt;/p&gt;
&lt;p&gt;I hope this article will be helpful to those who, like me, were vaguely aware of proxies in the past. Thank you.&lt;/p&gt;
&lt;h3&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dl.ebooksworld.ir/books/HTTP.The.Definitive.Guide.Brian.Totty.David.Gourley.OReilly.9781565925090.EBooksWorld.ir.pdf&quot;&gt;Http definitive guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;[10-minute Tektalk] 🐿 Jamie&apos;s Forward Proxy, Reverse Proxy, Load Balancer&quot;
image: &quot;https://i.ytimg.com/vi/YxwYhenZ3BE/maxresdefault.jpg&quot;
description: &quot;🙋‍♀️ This is a 10-minute tech talk from the crew at ElegantTechCourse. 🙋‍♂️&apos;10 Minute Tech Talks&apos; is a time for the Elegant Tech Course crew to share and talk about what they&apos;ve learned with their peers during the course. It&apos;s a time to share knowledge, talk, and reflect to help each other grow, and it&apos;s a self-directed...&quot;
url: &quot;https://www.youtube.com/watch?v=YxwYhenZ3BE&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Proxies&quot;
image: &quot;https://i.ytimg.com/vi/Je3PMpvwjtE/maxresdefault.jpg&quot;
description: &quot;#Developers #Proxy #몰컴⭐️ CodeFactory integration links (all courses and books) ⭐️https://links.codefactory.ai👉 NestJS Masterclasshttps://bit.ly/fcnestjs👉 Flutter Beginnerhttps://inf.run/Sjuw👉 Flutter Intermediatehttps://...&quot;
url: &quot;https://www.youtube.com/watch?v=Je3PMpvwjtE&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>ReverseProxy</category><category>ForwardProxy</category><category>Proxy</category><category>Network</category><author>Jinmu Go</author></item><item><title>Snails &apos;running their own race&apos;</title><link>https://jinmugo.com/en/posts/snail-sprinting-in-its-own-way/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/snail-sprinting-in-its-own-way/</guid><description>A short note of encouragement for people moving through each day at their own pace, like a snail sprinting in its own way.</description><pubDate>Wed, 04 Jun 2025 02:33:54 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;title: &quot;Stay strong&quot;
image: &quot;https://i.ytimg.com/vi/ufULhdEWlxE/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AHOBYAC0AWKAgwIABABGH8gKygrMA8=&amp;amp;rs=AOn4CLDs7_DLq83CwCqCHVVo1caN9OkCUw&quot;
description: &quot;#playlist #Fly #Band 00:01 Chow Chow04:23 Beautiful thing09:12 I13:24 Your words17:23 Will we be a song22:12 Saying I love you doesn&apos;t comfort me27:00 Is your night like my night30:45 Cohabitation35:10 Lilac38:40 I love you&quot;
url: &quot;https://www.youtube.com/watch?v=ufULhdEWlxE&amp;amp;t=2327s&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a playlist I&apos;ve been listening to a lot lately. It makes me feel like a cool person when I&apos;m having a hard time.
I especially like the pairing of Shujo Matsuoka&apos;s words at the beginning with Delice Peace&apos;s Chow Chow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!quote]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Just living day by day?
Don&apos;t know which way to go?
&quot;I want to feel alive!&quot;
It&apos;s simple.
Don&apos;t think about the past.
&quot;Why did I do that!&quot;
That just builds up anger.
Don&apos;t even think about the future.
&quot;Is it really going to be okay?&quot;
It just makes you worry.
What if it is?
Just do it!
You&apos;re betting your life on this moment!
Okay!
If everybody put their life on the line right now.
Everyone...
would be alive!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;The playlist is followed by the photo below.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s a pep talk to your own snail in a snail race, and it&apos;s unnecessarily comforting. Me, too. I can be comforted by a snail owner I&apos;ve never met in the UK who&apos;s been on the news for less than three seconds.
It&apos;s a good world.&lt;/p&gt;
&lt;p&gt;Dedicated to all snails who think they&apos;re slower than everyone else.&lt;/p&gt;
</content:encoded><category>snail</category><author>Jinmu Go</author></item><item><title>Using ssh-copy-id to easily set up remote connections</title><link>https://jinmugo.com/en/posts/ssh-copy-id/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/ssh-copy-id/</guid><description>How SSH public-key authentication works, how to register a key on a remote server with ssh-copy-id, and which sshd settings are required.</description><pubDate>Tue, 02 Sep 2025 08:17:04 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s really annoying to enter a password every time I want to SSH into a remote server. ssh supports various authentication methods such as GSSAPI, host-based, etc. but I usually use &lt;strong&gt;password (symmetric key encryption)&lt;/strong&gt; or &lt;strong&gt;public key method authentication&lt;/strong&gt;.
(If you are curious about ssh&apos;s authentication methods, check out the &lt;code&gt;AUTHENTICATION&lt;/code&gt; section of &lt;code&gt;man ssh&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;I&apos;m in the process of converting all of my ssh connections to public key authentication on all of my servers because I&apos;m tired of typing passwords. This is where the &lt;code&gt;ssh-copy-id&lt;/code&gt; command comes in, and today we&apos;re going to learn about this friend.&lt;/p&gt;
&lt;p&gt;But first, let&apos;s take a quick look at public key cryptography.&lt;/p&gt;
&lt;h2&gt;Public Key Cryptography&lt;/h2&gt;
&lt;p&gt;This is an authentication method that uses a private key and a public key. Unlike passwords, the keys used for encryption and decryption are different.&lt;/p&gt;
&lt;p&gt;In the public key method, there is a submitting side and a solving side. The test taker creates a mathematical problem based on the public key that is difficult to solve without the private key.
The problem solver cannot solve the problem without the private key, and only the person with the private key can solve the problem and authenticate it. Even if someone with the public key creates the problem, they cannot solve it unless they have the private key. This is why they are sometimes called asymmetric ciphers.&lt;/p&gt;
&lt;p&gt;This is why SSH also uses public key authentication.&lt;/p&gt;
&lt;h2&gt;public key password in SSH&lt;/h2&gt;
&lt;p&gt;There are four steps in the authentication process.&lt;/p&gt;
&lt;p&gt;Preparation -&amp;gt; Access request and information exchange -&amp;gt; Digital signature generation (client) -&amp;gt; Signature verification (server)&lt;/p&gt;
&lt;h3&gt;Preparation&lt;/h3&gt;
&lt;p&gt;In the preparation process, the client generates a private and public key with the &lt;code&gt;ssh-keygen&lt;/code&gt; command. You can specify the type of key you want to use with the &lt;code&gt;-t&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;The client also copies its public key to the remote server it wants to connect to and registers it in the &lt;code&gt;.ssh/authorized_keys&lt;/code&gt; file.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use &lt;code&gt;ssh-copy-id&lt;/code&gt; to do this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Requesting access and exchanging information&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;client requests SSH connection to server&lt;/li&gt;
&lt;li&gt;the server and user start encrypted communication, sharing temporary information such as a unique &lt;strong&gt;Session ID&lt;/strong&gt; that will be used only for this communication. This Session ID is a unique value that changes with each connection.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Generate digital signature (client)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;the client creates a message based on the session ID it just shared with the server.&lt;/li&gt;
&lt;li&gt;It then encrypts the message using its private key. The result is a digital signature.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Signature verification (server)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;the client sends the generated digital signature to the server.&lt;/li&gt;
&lt;li&gt;the server gets the public key in &lt;code&gt;authrized_keys&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;it uses this public key to verify that the digital signature sent by the client is valid.The verification process mathematically checks two things&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Was the signature really created with the private key paired with that public key?&lt;/li&gt;
&lt;li&gt;Does the signature match the session ID that was initially shared?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ssh-copy-id&lt;/h2&gt;
&lt;p&gt;As mentioned briefly above, the &lt;a href=&quot;#preparation&quot;&gt;Preparation&lt;/a&gt; process, the &lt;code&gt;ssh-copy-id&lt;/code&gt; is used. In public key authentication, it is necessary to add the client-generated public key to the remote server&apos;s &lt;code&gt;~/.ssh/authrized_keys&lt;/code&gt;, and this command simplifies this tedious task.&lt;/p&gt;
&lt;p&gt;The basic usage is as follows&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-copy-id [username]@[serveraddress]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, you can use the name of the &lt;code&gt;Host&lt;/code&gt; set in &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh-copy-id [hostname]
```bash ssh-copy-id [hostname

The following image shows how to set the public key to the remote `proxmox` host with `ssh-copy-id`.
![[ssh-copy-id-1756822514887.webp]]

&amp;gt; `-i` option to specify a specific public key file to copy.

### Execution process

1. **Run the command**:  Run the command to copy a specific public key file named `ssh-key-2025-07-31.key.pub` to the `proxmox` server.
2. connect to the remote server: connect to the server (`root@192.168.1.107`) to register the public key with the server.
3. Automatically copy and set up: If the user enters the correct password, `ssh-copy-id` will automatically add the public key to the remote server&apos;s `authorized_keys` file and set up the necessary permissions.
4. **Success**: A message &quot;1 key added&quot; will let you know that everything went well. From now on, you can connect directly with the specified key without a password.

If `ssh-copy-id` is not present, you will need to add it manually.

```bash
cat ~/.ssh/id_rsa.pub | ssh [username]@[serveraddress] \
&quot;mkdir -p ~/.ssh &amp;amp;&amp;amp; \
 touch ~/.ssh/authorized_keys &amp;amp;&amp;amp; \
 chmod 700 ~/.ssh &amp;amp;&amp;amp; \
 chmod 600 ~/.ssh/authorized_keys &amp;amp;&amp;amp; \
 cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this way.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ssh-copy-id&lt;/code&gt; is a command that handles this process automatically. The implementation consists of a shell script.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s about 416 lines long on MACOS, so if you&apos;re curious, you can open the file in the path specified by &lt;code&gt;which ssh-copy-id&lt;/code&gt; and check it out.&lt;/p&gt;
&lt;h2&gt;Set up the server-side sshd daemon&lt;/h2&gt;
&lt;p&gt;Even if you have successfully copied the public key using &lt;code&gt;ssh-copy-id&lt;/code&gt;, you will not be able to connect if the server&apos;s SSH configuration does not allow public key authentication.&lt;/p&gt;
&lt;p&gt;Open the remote server&apos;s &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; file to see and change the following entries&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# whether to allow public key authentication (required)
PubkeyAuthentication yes

# Location of the authorized public key list file
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Most modern Linux using Systemd (Ubuntu, CentOS 7+, etc.)
sudo systemctl restart sshd

# or
sudo systemctl restart ssh

# for older systems using init.d
sudo service ssh restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Cleanup&lt;/h2&gt;
&lt;p&gt;Public key authentication is a great way to avoid the hassle of entering a password every time you connect to a remote server.  However, the process of registering a public key with the server is more tedious than it sounds. It requires a combination of commands such as &lt;code&gt;mkdir&lt;/code&gt;, &lt;code&gt;touch&lt;/code&gt;, &lt;code&gt;chmod&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, and many others.&lt;/p&gt;
&lt;p&gt;Thankfully, &lt;code&gt;ssh-copy-id&lt;/code&gt; is here to save you from this mistake-prone process with a single command. It connects to the remote server, finds the &lt;code&gt;authorized_keys&lt;/code&gt; file, matches the permissions, and copies the keys, all in one command.
Now let&apos;s save ourselves the trouble with &lt;code&gt;ssh-copy-id&lt;/code&gt;.&lt;/p&gt;
</content:encoded><category>Linux</category><category>ssh</category><category>ssh-copy-id</category><author>Jinmu Go</author></item><item><title>4th Sunshine Run Half Marathon Recap</title><link>https://jinmugo.com/en/posts/sunshine-run-half-marathon/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/sunshine-run-half-marathon/</guid><description>Lessons about pacing and ambition from finishing my first official half marathon through changing weather and late-race shin pain.</description><pubDate>Fri, 05 Sep 2025 02:06:49 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I participated in the 4th annual Sunshine Run on August 30th. It was my first official half marathon since I started running, and I thought I&apos;d write about it because it was so memorable.&lt;/p&gt;
&lt;p&gt;First of all, I can&apos;t help but mention the weather. If you&apos;ll recall, the weather on race day, August 30, 2025, was pretty fickle. I can&apos;t tell you how many times the weather changed in the short two hours or so that I was running. It looked like it was going to rain at the start, then the sun came out halfway through the run, then it disappeared, then it rained again.... It was the most amazing weather. There was even a rainbow.
The good thing is that I love running in the rain. It&apos;s hard to wash your shoes afterward, but it&apos;s easier to breathe and the trees look prettier when they&apos;re wet.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The marathon started at 9:00am at Jamsil Sports Complex and I took the morning bus from Chuncheon to the subway to the starting point. I calculated the time beforehand, but I didn&apos;t have as much time as I thought, so I went to the starting line without warming up enough. It wasn&apos;t long before I realized that my body felt more saggy and heavy than I expected. But what the heck, the race had already started. The good news is that this time I wasn&apos;t running alone, but with people.&lt;/p&gt;
&lt;p&gt;The difference between running a half marathon alone and running with a group is that you can see each other. At the beginning of the race, I was thinking a lot. I would try to follow the pace of other people, I would look at the rules of the race, and I would think, &quot;How is that different from how I run, how does that person run so well?&quot; .... At the same time I was looking at other people, I was looking at myself.&lt;/p&gt;
&lt;p&gt;By the middle of the race, I started to think about other people a little less. No, I should say I couldn&apos;t. Because I was struggling right now. I was out of breath, my legs were hurting, and I couldn&apos;t afford to look at other people, so I just casually walked through the green and over the blue.
My goal for this marathon was to not walk once, but I couldn&apos;t do it. I had to stop at a pretty high hill in the middle of the marathon course. If it&apos;s uphill, it&apos;s downhill. It&apos;s a simple truth. And I hated that fact for a moment. If you don&apos;t control the downhills, you can get tired. You have to be careful.&lt;/p&gt;
&lt;p&gt;After 15 kilometers, I started to feel my body reaching its limits. Normally, I would have felt fine after this distance, but for some reason it was different today, especially my right shin. I kept going, resting, resting, resting.
When you run and walk, you start to see things you didn&apos;t see before, especially runners who stand out. People my age, older people, middle-aged people, and even children. It&apos;s a humbling world. I realize how big it is and how many people there are.&lt;/p&gt;
&lt;p&gt;In my experience, the 18th kilometer was the hardest. When I circled the course and saw the same 3 kilometers that I had passed so lightly the first time, I felt like I was in the middle of a 15-kilometer gap. In the last kilometer, I was running with a rat on my right shin. I wanted to finish in at least two hours, but I just couldn&apos;t muster up the strength.
The half marathon is a strange distance. It&apos;s obviously longer than 10 kilometers, but it&apos;s also closer than a full marathon. It&apos;s also an easy distance to get greedy. That&apos;s the beauty of the half. The condition of the day, the weather, the cheering of the crowd, someone&apos;s step, my breathing - everything affects the result. That&apos;s why it&apos;s a new race every time. I think I read a similar passage in Haruki Murakami&apos;s What I Want to Talk About When I Talk About Running once. It said that even if you&apos;re running the exact same route every time, that day&apos;s run will be unlike any other. I don&apos;t think my memory is perfect, but what the heck.&lt;/p&gt;
&lt;p&gt;If you&apos;re on the fence about running your first half, I encourage you to give it a go. Even in imperfect conditions, keep moving forward. This 4th Sunshine Run will be a bold mark in my running life. It&apos;s just the beginning. Until I conquer all the marathons in the world.&lt;/p&gt;
</content:encoded><category>marathon</category><category>running</category><category>sunshine-run</category><category>half-marathon</category><author>Jinmu Go</author></item><item><title>The mind behind linux</title><link>https://jinmugo.com/en/posts/the-mind-behind-linux/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/the-mind-behind-linux/</guid><description>About Open Source</description><pubDate>Fri, 19 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://youtu.be/o8NPllzkFhE?si=iX4O4Z0duW7-5Q7s&lt;/p&gt;
&lt;p&gt;When I first learned to develop, I remember having a hard time adjusting to the strange culture of &quot;open source&quot;. I remember when I was first introduced to this concept. In the movie industry I was working in, the way a person edited or shot a movie could become their identity.
So some people, myself included, kept these skills to themselves, not sharing them easily with others. I wouldn&apos;t say we hid them, I&apos;d say we didn&apos;t talk about them easily.
We didn&apos;t hide it, but there was something awkward about talking about these techniques and editing. It wasn&apos;t just movie footage, but I think it was similar when I asked my friends from other majors around me. They would tell you some things, but they wouldn&apos;t tell you everything easily. There was also a much smaller &quot;community&quot; to get this information from. I remember that I only learned by asking my seniors.&lt;/p&gt;
&lt;p&gt;So when I first started programming, I was surprised to see a lot of code on the internet. Many people were putting their time and effort into their code on the internet for anyone to see, and other programmers were using that code to build their own projects.
their own projects. If they see something in the code that they think could be improved, they contribute it themselves. Of course, the contributor and the original author of the code don&apos;t know each other.&lt;/p&gt;
&lt;p&gt;How did this unusual culture come about? How did &quot;open source&quot; turn people from closed-minded and hiding their skills to open-minded and open-minded? There are many influences, but a big one is Linus Torvalds&apos; Linux. Torvalds released the code for Linux, a project he had been working on for nearly a year and a half, to the Internet. Initially, he wondered if someone else would benefit from his hard work, but he didn&apos;t think twice about it and just thought, &quot;Why not?&quot;&lt;/p&gt;
&lt;p&gt;This small moment was the beginning of Linux, and as people around him became interested in it, contributing ideas and code reviews, it became the largest software project in history. In the video, Torvalds said &quot;For me, the really important moments are not when something becomes big, but when it becomes small.&quot; It seems Torvalds understood the power of small things. Linux is a big project now, but it wouldn&apos;t be where it is today without the contributions of each and every one of those early contributors.&lt;/p&gt;
&lt;p&gt;Linux is the foundation for a huge amount of open source software around the world. Linux, mysql, git, php, swift, node.js, etc. are some examples. It is safe to say that there is no software we use today that does not use open source technologies. It&apos;s great to be able to share the perspectives of different people from around the world and see the code they&apos;ve worked so hard to create for free.&lt;/p&gt;
&lt;p&gt;The philosophy of open source continues to expand. Web encyclopedias like Wikipedia and Wikipedia were created. Encyclopedias have evolved from the idea that encyclopedias are difficult things created by experts and corporations to the idea that anyone can contribute their knowledge and others can edit it to make it more accurate. I wonder what the future of open source will be. In the video, the host asks: &quot;Is the idea of open source fully realized in the world, or is there still a way to go?&lt;/p&gt;
&lt;p&gt;Torvalds replies. &quot;Open source is not just about programming, it has also influenced scientific journals and encyclopedias. I&apos;m not a prophet and it&apos;s not up to me to say something new.&quot;&lt;/p&gt;
</content:encoded><category>Linux</category><category>linus torvalds</category><category>open source</category><author>Jinmu Go</author></item><item><title>Trie - feat. LeetCode 208. Implement Trie</title><link>https://jinmugo.com/en/posts/trie-feat-leetcode-208/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/trie-feat-leetcode-208/</guid><description>re&quot;trie&quot;val</description><pubDate>Thu, 02 Jul 2026 06:16:59 GMT</pubDate><content:encoded>&lt;p&gt;A summary of Tries, written while solving the LeetCode 208: Implement Trie problem.&lt;/p&gt;
&lt;p&gt;A Trie is a &lt;strong&gt;tree-based data structure specialized for string search&lt;/strong&gt;. The name is derived from “re&lt;strong&gt;trie&lt;/strong&gt;val (search),” and it is frequently used in problems requiring prefix search.
The simplest way to store strings is to use an array or a hash map.&lt;/p&gt;
&lt;p&gt;For example, consider an autocomplete feature.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;algori&quot;  →  algorithm, algorithm problems, how to study algorithms ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The simplest approach to implementing this feature is linear search, where all words are stored in an array and compared one by one.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;From [&quot;apple&quot;, &quot;app&quot;, &quot;april&quot;, &quot;apply&quot;, ...],
select only words starting with &quot;app&quot; → check them all by iterating through the list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This wouldn’t be a problem if there were only 10 words, but what if there are hundreds of thousands of words registered in the dictionary? Scanning the entire list every time a search term is entered would be too slow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What about a HashMap?&lt;/strong&gt; If you store the entire word in a HashMap, the problem can be solved in O(1) time complexity. However, a HashMap can only find exact matches. What if you want to find all words that start with the prefix “app”? You’d have no choice but to iterate through the entire list again.&lt;/p&gt;
&lt;p&gt;This is where the idea of a &lt;strong&gt;Trie&lt;/strong&gt; comes in.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Search&lt;/th&gt;
&lt;th&gt;Prefix Search&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Array + Linear Search&lt;/td&gt;
&lt;td&gt;O(N * L)&lt;/td&gt;
&lt;td&gt;O(N * L)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hash Map&lt;/td&gt;
&lt;td&gt;O(L) (average)&lt;/td&gt;
&lt;td&gt;O(N * L)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trie&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O(L)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O(L)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;N = number of stored words, L = string length&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The key point is that &lt;strong&gt;a Trie maintains O(L) complexity even for prefix searches&lt;/strong&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A Trie is a tree structure composed of interconnected nodes. The key differences from a regular tree are as follows.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Regular Tree&lt;/strong&gt;: Stores the entire data (a single word) in a single node.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trie&lt;/strong&gt;: Stores only &lt;strong&gt;one character&lt;/strong&gt; per node.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A trie node typically contains two types of information.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Children&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;References to child nodes linked to the next character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;IsEnd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A flag indicating whether this node is the end of a word&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For example, if the two words &lt;code&gt;&quot;app&quot;&lt;/code&gt; and &lt;code&gt;&quot;apple&quot;&lt;/code&gt; are stored in a trie, the structure looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; (Root)
 |
 a
 |
 p
 |
 p  ← IsEnd = true  (&quot;app&quot; completed)
          |
 l
 |
 e  ← IsEnd = true  (&quot;apple&quot; complete)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;&quot;app&quot;&lt;/code&gt; and &lt;code&gt;&quot;apple&quot;&lt;/code&gt; share the prefix &lt;code&gt;&quot;app&quot;&lt;/code&gt;, there are no duplicate nodes for that segment. This is a key feature of a trie.&lt;/p&gt;
&lt;p&gt;The three most basic operations of a trie are as follows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Insert&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start at the root node.&lt;/li&gt;
&lt;li&gt;Check for child nodes in order, starting with the first letter of the word.
&lt;ul&gt;
&lt;li&gt;If none exist: Create and add a new node.&lt;/li&gt;
&lt;li&gt;If there is one: Move to that node.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When you reach the last character of the word, set the node’s &lt;code&gt;IsEnd&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Search&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start at the root node.&lt;/li&gt;
&lt;li&gt;Traverse the tree following the characters of the word.
&lt;ul&gt;
&lt;li&gt;If there are no child nodes along the way → return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When you reach the end of the word, return the value of &lt;code&gt;IsEnd&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;StartsWith (Prefix Search)&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Traverse down the word (prefix) in the same way as Search.&lt;/li&gt;
&lt;li&gt;Check only whether the end of the word has been reached. Do not check &lt;code&gt;IsEnd&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;In other words, if even one word begins with the given prefix, return &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The existence of &lt;code&gt;StartsWith&lt;/code&gt; is the key feature that distinguishes a trie from an array or a hash map. It allows us to determine whether a word exists in O(L) time based solely on the prefix.&lt;/p&gt;
&lt;p&gt;Below is my Go implementation of &lt;a href=&quot;https://leetcode.com/problems/implement-trie-prefix-tree/description/&quot;&gt;LeetCode Problem 208&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type TrieNode struct {
    Children map[rune] *TrieNode
    IsEnd bool
}

func NewTrieNode() *TrieNode {
    return &amp;amp;TrieNode {
 Children: make(map[rune]*TrieNode),
 IsEnd: false,
    }
}

type Trie struct {
    Root *TrieNode
}

func Constructor() Trie {
    return Trie{
    Root: NewTrieNode(),
    }
}

func (this *Trie) Insert(word string) {
    current := this.Root

 for _, char := range word {
 if _, exists := current.Children[char]; !exists {
 current.Children[char] = NewTrieNode()
 }

 current = current.Children[char]
    }

    current.IsEnd = true
}

func (this *Trie) Search(word string) bool {
    current := this.Root

 for _, char := range word {
 if nextNode, exists := current.Children[char]; exists {
            current = nextNode
 } else {
 return false
 }
    }

 return current.IsEnd
}

func (this *Trie) StartsWith(prefix string) bool {
    current := this.Root

    for _, char := range prefix {
 if nextNode, exists := current.Children[char]; exists {
 current = nextNode
 } else {
 return false
 }
    }

 return true
}


/**
 * Your Trie object will be instantiated and called as follows:
 * obj := Constructor();
 * obj.Insert(word);
 * param_2 := obj.Search(word);
 * param_3 := obj.StartsWith(prefix);
 */
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since a Trie can perform prefix searches in O(L) time, it is useful in situations such as the following.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Autocomplete&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It must find and suggest all words that begin with the prefix entered by the user. A trie uses &lt;code&gt;StartsWith&lt;/code&gt; to check for the presence of a prefix, then traverses all &lt;code&gt;IsEnd&lt;/code&gt; nodes under that node to return a list of candidates. While a hash map must iterate through the entire list of words, a trie only needs to search the subtree corresponding to the prefix.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spell Checker&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Used to quickly verify whether a given word exists in a dictionary. The &lt;code&gt;Search&lt;/code&gt; operation can be performed in O(L) time, and the more words registered in the dictionary, the more efficient it becomes compared to arrays or hash maps. Trie traversal is also often used when implementing recommendations for similar words (based on Levenshtein distance).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP Routing (Longest Prefix Match)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When routing IP addresses in a network, the longest matching prefix with the destination IP must be found. Tries are used in the form of binary trie or Patricia trie and are optimized for prefix-based longest match searches.&lt;/p&gt;
&lt;p&gt;Tries are data structures that shine brightest in string search scenarios, particularly when &lt;strong&gt;prefix search&lt;/strong&gt; must be solved in O(L) time. They store only one character per node and sacrifice space in exchange for search efficiency by sharing common prefixes. To summarize the differences from the data structures discussed earlier:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Structure&lt;/th&gt;
&lt;th&gt;Search&lt;/th&gt;
&lt;th&gt;Prefix Search&lt;/th&gt;
&lt;th&gt;Major Drawbacks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Array + Linear Search&lt;/td&gt;
&lt;td&gt;O(N·L)&lt;/td&gt;
&lt;td&gt;O(N·L)&lt;/td&gt;
&lt;td&gt;Slow search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hash Map&lt;/td&gt;
&lt;td&gt;O(L)&lt;/td&gt;
&lt;td&gt;O(N·L)&lt;/td&gt;
&lt;td&gt;Cannot perform prefix search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trie&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O(L)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O(L)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High memory usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Is prefix search required?&lt;/strong&gt; → Trie&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is only an exact match required?&lt;/strong&gt; → HashMap&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is the dataset small?&lt;/strong&gt; → An array is sufficient&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have time, I recommend trying the problems below as well.&lt;/p&gt;
&lt;p&gt;LeetCode 208. &lt;a href=&quot;https://leetcode.com/problems/implement-trie-prefix-tree/&quot;&gt;Implement Trie (Prefix Tree)&lt;/a&gt;
LeetCode 1268. &lt;a href=&quot;https://leetcode.com/problems/search-suggestions-system/&quot;&gt;Search Suggestions System&lt;/a&gt;&lt;/p&gt;
</content:encoded><category>trie</category><author>Jinmu Go</author></item><item><title>Why does a magic packet repeat its MAC address 16 times?</title><link>https://jinmugo.com/en/posts/wake-on-lan-mac-address-16-times/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/wake-on-lan-mac-address-16-times/</guid><description>Why a Wake-on-LAN magic packet contains six FF bytes followed by the target MAC address repeated 16 times, explained through frame layout and detection.</description><pubDate>Sun, 17 Aug 2025 12:25:50 GMT</pubDate><content:encoded>&lt;p&gt;I recently built a proxmox server using an unused computer. While I was having fun building my home server, I thought to myself, &quot;I know how to turn off a computer remotely with ssh and use things like &lt;code&gt;shutdown&lt;/code&gt;, &lt;code&gt;halt&lt;/code&gt;, and &lt;code&gt;poweroff&lt;/code&gt;, but is it possible to turn on a computer that is off remotely?&quot; I thought to myself.&lt;/p&gt;
&lt;p&gt;I found out that it can be implemented through a technology called Wake-on-LAN (WoL), and while researching, I found something very curious, so I&apos;m going to write a short blog post about it.&lt;/p&gt;
&lt;p&gt;WoL is a technology that sends a signal over the network to wake up a computer in a low-power state. And what makes this possible is a piece of data called a &quot;magic packet,&quot; which, if you look at the structure of the magic packet, sends the MAC address, which is the unique address of the computer, exactly the same 16 times. I&apos;m curious about how this mysterious number of 16 (instead of 4 or 8) came to be, so I&apos;m going to dig into it.&lt;/p&gt;
&lt;h2&gt;WoL and magic packets&lt;/h2&gt;
&lt;p&gt;First, let&apos;s quickly review what Wake on LAN (WoL) and Magic Packets are.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Wake on LAN (WoL): WoL is the protocol name given to the Magic Packet technology.  It is used to remotely wake up a powered off or sleeping PC over the network.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Magic Packet: An Ethernet frame with a special data pattern. This packet is detected by the receiving Ethernet controller and is responsible for waking up the computer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Structure of a magic packet (Ethernet frame)&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;As mentioned earlier, a magic packet is an Ethernet frame with a specialized data pattern. To understand the structure of a magic packet, we need to know about Ethernet frames.&lt;/p&gt;
&lt;p&gt;An Ethernet frame is defined by a total of five fields.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MAC dest: Destination MAC address, which means the physical address of the network device that will receive this packet. Usually, the broadcast address &lt;code&gt;FF:FF:FF:FF:FF:FF:FF:FF&lt;/code&gt; is used to signal all devices in the network. 2.
MAC src: Source MAC address. The MAC address of the device sending this packet.&lt;/li&gt;
&lt;li&gt;MISC (Misc., etc.): This is the area containing the EtherType, which indicates the type of Ethernet frame. It serves to indicate what kind of data this packet is.&lt;/li&gt;
&lt;li&gt;Data / Payload: This is the part that contains the actual data to be transmitted. It includes headers and data from higher layers (e.g. TCP/IP). If the size of the data is smaller than 46 bytes, padding is added to meet the minimum size.&lt;/li&gt;
&lt;li&gt;CRC (Cyclic Redundancy Check): A sequence of frame checks to detect errors that may occur during transmission. It checks for integrity similar to a hash algorithm, but more on that later.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note]+ padding of Ethernet frames
In the early days of Ethernet, all computers shared a single communication line and communicated according to a convention called CSMA/CD. CD is Collision Detection, and if two computers send data at the same time, causing a &apos;collision&apos;, the sender detects this collision, stops sending data, and resends it.
The reason why the data in an Ethernet frame is smaller than 46 bytes and needs to be filled with 46 bytes is because of Collision Detection. If the data packets were too small, data collisions on the network would not be recognized by the sender and would pass by without being resent.
If A sends a packet that is too small and ends the transmission in a split second, A doesn&apos;t realize that the data is broken and the data is lost.
To ensure that collisions could be detected in this scenario, the engineers decided to arbitrarily increase the length of the data by adding padding. The defined size was 64 bytes, and the minimum size of the actual data (64 - 18) was calculated to be 46 bytes, excluding 18 bytes of basic information in the frame.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Magic Pattern&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;MAGIC Pattern&lt;/strong&gt; shown in the figure will be placed in the Payload field. The magic pattern consists of 102 bytes in total and can be divided into two parts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FF ... FF (6 bytes): This is called the Synchronization Stream and contains six consecutive &lt;code&gt;FF&lt;/code&gt; values, which helps the Ethernet controller on the receiving end to easily scan and detect the magic packet.&lt;/li&gt;
&lt;li&gt;MAC 6 * 16 (96bytes): **This is where we repeat the MAC address we want to wake up 16 times. This is the core of the magic pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, Secure On Password allows you to set a password of 6 bytes in size, which is used by some WoL technologies to increase security. It is only used when the feature is enabled and prevents unauthorized users from remotely turning on the computer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!note]+ How synchronization streams make detection easier.
Synchronization streams make the scanning state machine much simpler. The scanning state machine is the hardware logic inside the Ethernet controller that analyzes incoming data to look for specific patterns.
If there were no synchronization stream, the Ethernet controller would have to keep checking every incoming byte sequence to see when the pattern of a 6-byte MAC address repeated 16 times would start. This becomes a more complex and power hungry operation.
But if a clear and distinctive synchronization stream called FF ... FF comes first, the controller can start scanning for subsequent MAC address patterns only when it detects this six-byte sequence. In other words, the synchronization stream acts as a beacon or marker, helping the controller minimize unnecessary scanning and focus on finding patterns only when it needs to.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that we&apos;ve rambled on for a bit, let&apos;s take a look at why MAC addresses are sent 16 times in a row.&lt;/p&gt;
&lt;h2&gt;Why repeat the MAC address 16 times?&lt;/h2&gt;
&lt;p&gt;I searched for an answer to this question in Korean articles, but there was no answer except &quot;This is what happens when you send a packet like this!&quot; and even when I asked Gemini, they gave me the following strange answer.&lt;/p&gt;
&lt;p&gt;For reference, the question was: **Why does the magic packet repeat the MAC address 16 times instead of just another number?&lt;/p&gt;
&lt;p&gt;
~~clap~!&lt;/p&gt;
&lt;p&gt;I came across a 2014 article on a site called serverfault that kind of answered the question. It&apos;s not an official document, and it&apos;s not accurate, but the logic of the answerer convinced me, so I pulled it up.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Why does a Wake-On-LAN packet contain 16 duplications of the target MAC address?&quot;
image: &quot;https://cdn.sstatic.net/Sites/serverfault/Img/apple-touch-icon@2.png?v=9b1f48ae296b&quot;
description: &quot;From the Wireshark webpage: The Target MAC block contains 16 duplications of the IEEE address of the target, with no breaks or interruptions. Is there any specific reason for the 16 duplications?&quot;
url: &quot;https://serverfault.com/questions/632908/why-does-a-wake-on-lan-packet-contain-16-duplications-of-the-target-mac-address&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key is simplicity and reliability of the implementation.&lt;/p&gt;
&lt;p&gt;When AMD and Hewltt Packard (HP) first created Magic Packet, their goal was to add the feature as little as possible to the existing hardware configuration, so they decided to utilize the address matching circuitry already present in Ethernet controllers for Magic Packet detection.
The address matching circuitry is responsible for identifying and receiving only the frames that match the MAC address of the PC in question out of the many incoming Ethernet frames on the network. To add the ability to detect magic packets, we simply added a counter that repeatedly counts the MAC address 16 times.&lt;/p&gt;
&lt;p&gt;We use a 4-bit counter that can hold values from 0 to 15, which allows for simple logic to execute wakeup code when the counter overflows (15+1=0). According to the pseudo code in the link above, it looks like this&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Initialize a single counter that holds values from 0-15.
Set it to 0.
Watch the network. When I see the signal:
Loop:
  Do I see my address at the right spot?
  Yes: Add 1 to counter.
    Did I just overflow? (15+1 = 0?)
    Yes: Jump out of loop to &quot;wake up&quot; code.
...otherwise
Loop again.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is all about the simplicity of the implementation, and the number 16 comes from the reliability of the implementation. As mentioned earlier, the Internet is a fast-paced environment with lots of information flowing back and forth. To prevent a random stream of data from becoming a command to turn on a system, it needs to be easily identifiable and have little chance of false positives.&lt;/p&gt;
&lt;h3&gt;What if we use a 2-bit counter?&lt;/h3&gt;
&lt;p&gt;If we were to use a 2-bit counter to repeat the MAC address only 4 times, it would be 24 bytes, which is less than the minimum size of frame data (46 bytes), so we would add padding. This would make it much more likely that such a sequence would occur on the network by chance, greatly increasing the chance of unintentionally waking up the system. It would also have weakened the characteristics that distinguish magic packets from other network traffic, making them less reliable.
To summarize, using a 2-bit counter to iterate the MAC address only 4 times would have maintained the simplicity of the hardware implementation, but would have been significantly worse than the current 16 iterations in terms of &quot;misbehavior prevention&quot; and &quot;high reliability&quot;, two of the most important goals.&lt;/p&gt;
&lt;h3&gt;What if we use 8-bit counters?&lt;/h3&gt;
&lt;p&gt;An 8-bit counter can represent values from 0 to 255, and in order for the counter to overflow (255+1=0), the MAC address must be repeated 256 times. Since a MAC address is 6 bytes, 256 iterations would be &lt;strong&gt;1,536 bytes&lt;/strong&gt;. This exceeds the maximum size of an Ethernet frame, so it is not feasible in practice, and even if it were, the frame would be unnecessarily large and we would have to move a lot of data around pointlessly.&lt;/p&gt;
&lt;h3&gt;4-bit counter&lt;/h3&gt;
&lt;p&gt;So why a 4-bit counter? Let&apos;s put the previous hypotheses together&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A 2-bit counter (iterated 4 times) is too risky ** The payload size is too small, increasing the chance of false positives. There was a risk that data on the network could be accidentally recognized as a magic packet, causing the system to turn on unwantedly. **Failed on reliability grounds.&lt;/li&gt;
&lt;li&gt;The payload size exceeds the Ethernet maximum transmission unit (MTU), making it impossible to transmit over standard networks in the first place. Rejected for &lt;strong&gt;practicality&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end, a 4-bit counter (16 iterations) was the sweet spot that solved both problems. It is long enough (96 bytes) to maximize reliability, while remaining fully compliant with the Ethernet frame standard and not losing practicality. At the same time, it minimized the complexity of the hardware, as it could be implemented as a simple 4-bit counter.&lt;/p&gt;
&lt;p&gt;Within these constraints, 16 was the number that captured the best of both worlds: reliability, efficiency, and simplicity.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;What started as a curiosity about the number 16 while simply configuring a home server has led me to this point. With the limited resources of early Ethernet controllers, minimum frame sizes, and the need to distinguish between random data and signals, engineers found a solution.
The fact that such a seemingly trivial technical detail has such a rational reason and solution is one of the true fascinations of engineering.&lt;/p&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;WakeOnLAN - Wireshark Wiki&quot;
image: &quot;https://www.wireshark.org/assets/img/wireshark-logo.png&quot;
description: &quot;WakeOnLAN is the protocol name given to the so-called Magic Packet technology, developed by AMD and Hewlett Packard for remotely waking up a remote host that may have been automatically powered-down because of its power management features. Although power management allows companies and individuals to cut power usage costs, it presents a problem for IT departments especially in being able to quickly and efficiently remotely manage PC&apos;s, especially during off-hours operation when those PC&apos;s are most likely to be in a suspended or standby state, assuming power management features are enabled.&quot;
url: &quot;https://wiki.wireshark.org/WakeOnLAN&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;Wake-on-LAN - Wikipedia&quot;
image: &quot;https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/Wake_on_LAN_connector.JPG/1200px-Wake_on_LAN_connector.JPG&quot;
description: &quot;Wake-on-LAN (WoL)[a] is an Ethernet or Token Ring computer networking standard that allows a computer to be turned on or awakened from sleep mode by a network message. The message is usually sent to the target computer by a program executed on a device connected to the same local area network (LAN). It is also possible to initiate the message from another network by using subnet directed broadcasts or a WoL gateway service. It is based upon AMD&apos;s Magic Packet Technology, which was co-developed by AMD and Hewlett-Packard, following its proposal as a standard in 1995. The standard saw quick adoption thereafter through IBM, Intel and others.&quot;
url: &quot;https://en.wikipedia.org/wiki/Wake-on-LAN&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;title: &quot;20213.pdf&quot;
image: &quot;https://t3.gstatic.com/faviconV2?client=SOCIAL&amp;amp;type=FAVICON&amp;amp;fallback_opts=TYPE,SIZE,URL&amp;amp;url=https://www.amd.com/content/dam/amd/en/documents/archived-tech-docs/white-papers/20213.pdf&amp;amp;size=128&quot;
description: &quot;Publication# 20213&quot;
url: &quot;https://www.amd.com/content/dam/amd/en/documents/archived-tech-docs/white-papers/20213.pdf&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded><category>WOL</category><category>WakeOnLan</category><category>MagicPacket</category><category>Network</category><category>Ethernet</category><category>Hardware</category><author>Jinmu Go</author></item><item><title>Deploy a Zotero WebDAV Server on Coolify to Synchronize Attachments</title><link>https://jinmugo.com/en/posts/zotero-webdav-coolify/</link><guid isPermaLink="true">https://jinmugo.com/en/posts/zotero-webdav-coolify/</guid><description>How to deploy a WebDAV server on Coolify to sync PDF attachments from your Zotero personal library, and securely configure HTTPS, persistent storage, and backups.</description><pubDate>Tue, 25 Mar 2025 04:46:34 GMT</pubDate><content:encoded>&lt;p&gt;To use a WebDAV server hosted directly by Zotero, simply &lt;strong&gt;link a persistent storage location and authentication credentials to a WebDAV container, make it publicly accessible via an HTTPS domain, and then run “Server Verification” in Zotero&lt;/strong&gt;. I deployed &lt;a href=&quot;https://github.com/hacdias/webdav&quot;&gt;hacdias/webdav&lt;/a&gt; to Coolify, a spare OCI instance I had available.&lt;/p&gt;
&lt;p&gt;First, let’s clearly define the scope.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Synchronization Target&lt;/th&gt;
&lt;th&gt;Responsible Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bibliographic entries, collections, tags, notes&lt;/td&gt;
&lt;td&gt;Zotero Data Sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attachments (PDFs, images, etc.) in personal libraries&lt;/td&gt;
&lt;td&gt;The WebDAV server described in this post&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Group library attachments&lt;/td&gt;
&lt;td&gt;Supported only by Zotero Storage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;WebDAV does not replace the entire Zotero account. According to the official documentation, WebDAV is used &lt;strong&gt;only for syncing attachments in personal libraries&lt;/strong&gt; and cannot be used for group libraries.&lt;/p&gt;
&lt;h2&gt;Why I Set It Up Myself&lt;/h2&gt;
&lt;p&gt;I wanted to read PDFs in Zotero, add highlights and notes, and then continue viewing the same attachments on my iPad and MacBook.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Zotero Storage is the simplest option and offers good compatibility, but if you exceed the free attachment quota, you’ll need a paid plan.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since I already had a server up and running, I chose WebDAV. If you have to pay for a new VPS solely for this purpose, it’s better to first compare the costs—including server fees, updates, and backup time—with Zotero Storage.&lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The request path is simple.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Zotero → HTTPS domain → Coolify reverse proxy → webdav:6065 → /data
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Coolify handles the TLS certificate and external domain.&lt;/li&gt;
&lt;li&gt;The WebDAV container runs on internal port &lt;code&gt;6065&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data&lt;/code&gt; is stored on a volume that persists after redeployment.&lt;/li&gt;
&lt;li&gt;The username and password are injected as Coolify environment variables.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1. Create a WebDAV Configuration File&lt;/h2&gt;
&lt;p&gt;You do not need to copy the entire example configuration. The minimum configuration required for Zotero is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;address: 0.0.0.0
port: 6065
tls: false
behindProxy: true
directory: /data
permissions: CRUD

users:
  - username: &quot;{env}ENV_USERNAME&quot;
    password: &quot;{env}ENV_PASSWORD&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason &lt;code&gt;tls: false&lt;/code&gt; is set is because Coolify handles TLS termination. If you expose the container directly to the internet via a port, you should not use this configuration as-is. Since Zotero login credentials are transmitted via HTTP Basic authentication, external access must use HTTPS.&lt;/p&gt;
&lt;p&gt;No CORS settings have been included. Since the Zotero desktop and mobile apps are not web apps that &lt;code&gt;fetch&lt;/code&gt; from different origins in a browser, a CORS allowlist is not required for this configuration.&lt;/p&gt;
&lt;h2&gt;2. Preparing a Container with a Fixed Version&lt;/h2&gt;
&lt;p&gt;Create a Dockerfile application in Coolify and enter the following two lines:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM ghcr.io/hacdias/webdav:v5.15.0
ENTRYPOINT [&quot;webdav&quot;, &quot;-c&quot;, &quot;/config.yml&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of using &lt;code&gt;latest&lt;/code&gt;, I specified a fixed version that I verified. This prevents the system from automatically pulling new images and causing unexpected behavior changes; for updates, I check the release notes and then change the tag.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Set the application’s exposed port to &lt;code&gt;6065&lt;/code&gt; and connect a domain. The WebDAV process must accept incoming connections from all interfaces (&lt;code&gt;0.0.0.0&lt;/code&gt;) so that the Coolify proxy can access it.&lt;/p&gt;
&lt;h2&gt;3. Persist Settings and Data&lt;/h2&gt;
&lt;p&gt;Create two entries in Coolify’s &lt;strong&gt;Persistent Storage&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Configuration file: Use File Mount to mount the YAML above to &lt;code&gt;/config.yml&lt;/code&gt; as read-only.&lt;/li&gt;
&lt;li&gt;Attachments: Use Volume Mount to mount to &lt;code&gt;/data&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The container’s file system may change when redeploying. If you do not mount &lt;code&gt;/data&lt;/code&gt; to a persistent volume, you may lose your attachments.&lt;/p&gt;
&lt;h2&gt;4. Configuring Credentials and the HTTPS Domain&lt;/h2&gt;
&lt;p&gt;Add the following two values to &lt;strong&gt;Environment Variables&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ENV_USERNAME&lt;/code&gt;: The username to enter in Zotero&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENV_PASSWORD&lt;/code&gt;: A long, unique password&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Do not write the password directly in the Dockerfile or in the repository. After deployment, verify that you can access the HTTPS domain issued by Coolify, and do not leave port &lt;code&gt;6065&lt;/code&gt; open to the outside.&lt;/p&gt;
&lt;h2&gt;5. Connecting to WebDAV in Zotero&lt;/h2&gt;
&lt;p&gt;Go to &lt;strong&gt;Settings → Synchronization → File Synchronization&lt;/strong&gt; in Zotero.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Change the “My Library Attachments Synchronization Tool” to &lt;strong&gt;WebDAV&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;https&lt;/code&gt; as the protocol.&lt;/li&gt;
&lt;li&gt;Enter only the domain in the URL field. Zotero will automatically append &lt;code&gt;/zotero&lt;/code&gt; to the end.&lt;/li&gt;
&lt;li&gt;Enter the values for &lt;code&gt;ENV_USERNAME&lt;/code&gt; and &lt;code&gt;ENV_PASSWORD&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Server Verification&lt;/strong&gt; to confirm that the connection is successful.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If the validation is successful, click the Sync button and try uploading a small PDF file to start. You must log in to the same Zotero account on another device and verify that the attachments open before the setup is complete.&lt;/p&gt;
&lt;h2&gt;Things to Check Before Going Live&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Backup:&lt;/strong&gt; Coolify’s persistent volume is not a backup. Periodically copy the &lt;code&gt;/data&lt;/code&gt; directory to another server or object storage and test actual restoration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Updates:&lt;/strong&gt; Fix image tags, and manually upload new versions after backing them up.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTPS:&lt;/strong&gt; To protect credentials and files, use only HTTPS for external URLs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage:&lt;/strong&gt; Monitor server disk usage and backup retention periods.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope of Issues:&lt;/strong&gt; Zotero does not support issues specific to WebDAV. If a problem arises, first check the server logs, storage permissions, certificates, and the &lt;code&gt;/zotero&lt;/code&gt; path.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Self-hosting is quite satisfactory when utilizing existing server resources. However, “the container running” and “attachments being secure” are two separate issues. Only when you have permanent storage, off-site backups, and restoration testing in place can it truly be called an alternative to Zotero Storage.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zotero.org/support/sync&quot;&gt;Official Zotero Synchronization Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zotero.org/support/preferences/sync&quot;&gt;Zotero Sync Configuration Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hacdias/webdav&quot;&gt;hacdias/webdav Repository and Configuration Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hacdias/webdav/releases/tag/v5.15.0&quot;&gt;hacdias/webdav v5.15.0 Release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coolify.io/docs/applications/build-packs/dockerfile&quot;&gt;Coolify Dockerfile Deployment Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coolify.io/docs/knowledge-base/persistent-storage&quot;&gt;Coolify Persistent Storage Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>zotero</category><category>coolify</category><category>webdav</category><author>Jinmu Go</author></item><item><title>Week 21 - The Beginning.</title><link>https://jinmugo.com/en/weekly/2026-W21/</link><guid isPermaLink="true">https://jinmugo.com/en/weekly/2026-W21/</guid><description>A look back at exercise, certification prep, the Cinch side project, returning to reading, and preparing to leave for the United States in week 21 of 2026.</description><pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Workout Log&lt;/h2&gt;
&lt;p&gt;Recent Running Log&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![[2026-W20-1779267190791.webp]]
![[2026-W20-1779267207541.webp]]
![[2026-W20-1779267306603.webp]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following last year, I plan to run the Chuncheon Marathon again this year. My goal for this year is to break four hours. I haven’t really been training properly yet... but just to maintain my current level, I’m running at least three times a week.
Even that is a struggle, so I rarely go beyond 5 km. My goals and actions are a bit out of sync, but at least I’m consistently running three times a week—that’s something.&lt;/p&gt;
&lt;h2&gt;Heo Gan-min&lt;/h2&gt;
&lt;p&gt;If I had to name one of the things that’s made me happiest lately, it would be listening to Heo Gan-min while running. Heo Gan-min is
an abbreviation created by taking the first characters from Heo&lt;strong&gt;ki&lt;/strong&gt; Shibasaki, Kim&lt;strong&gt;gan&lt;/strong&gt;ji, and Kim&lt;strong&gt;min&lt;/strong&gt;kyung.
It all started with a segment called “B-Mainstream Invitation” on the Toss channel “Moneygraphy,” where these three appeared to discuss movies.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Rwx2EGl7i2U&quot;&gt;Masterpiece Movie World Cup with Three Grumpy Cinephiles | B-Mainstream Guest Spot: Heo-ki Shibaseki&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ve always enjoyed listening to podcasts while running, but lately I’ve become completely hooked on this trio. In my opinion, it’s the best content of the year. It’s fun to watch the videos, but it’s also enjoyable to just listen without thinking while running, and the occasional “fun button” moments are a real treat.
I’m also listening to all the podcasts featuring Kim Min-kyung. She’s been very active for a while now, so I’m happy to have so much to listen to these days.&lt;/p&gt;
&lt;h2&gt;Job Hunting.&lt;/h2&gt;
&lt;p&gt;I’m preparing for a job. To be honest, I don’t think I’m doing it properly—I don’t seem to have a sense of urgency. I have a resume and cover letter I wrote earlier, but there’s a lot that needs tweaking. While I’m at it, I’ve applied for the National Employment Program to receive employment support benefits. I have to meet with a counselor in person regularly to make a concrete plan for how to find a job. At first, I thought it would be a bit of a hassle, but preparing with someone else is definitely easier than doing it alone. Voicing my thoughts to someone else really helps me organize my thoughts. After all, we have to live with other people.&lt;/p&gt;
&lt;p&gt;On the 9th, I took the second part of the Linux Master Level 1 exam. I failed last year, so I resolved to give it another shot this time. Based on my preliminary scoring, I passed, but since it’s not certain yet, I’ll be a bit anxious until the results are announced on the 29th. Lately, I’ve been thinking I need to find a job, so I’ve been working on getting various certifications, though I’ll admit there’s a bit of anxiety driving me to do so. Still, it feels like I’m studying and reaching milestones, so I’m enjoying the process as if I were playing a game. This week, I took the written exam for the Certified Information Systems Auditor (CISA). The scores were posted immediately. Now I need to prepare for the practical exam.&lt;/p&gt;
&lt;h3&gt;Cinch&lt;/h3&gt;
&lt;p&gt;I’m working on a side project called &lt;a href=&quot;https://cinchcli.com&quot;&gt;Cinch&lt;/a&gt;. It’s the first project I’ve undertaken with the goal of generating revenue. I started it because I wanted to experience making money, even if it’s just a small amount. Of course, there’s a lot of talk these days that SaaS is dead (or will die) because of AI, but I still felt I should try doing what I can right now.&lt;/p&gt;
&lt;p&gt;Cinch is a clipboard service. I’m still pivoting a lot, so I can’t define it clearly yet, but my goal is to create a clipboard service that’s easy to use today. I started out with a remote clipboard tool, but as I built it, my ambitions grew. However, making something that people actually want to use and find easy to use is incredibly difficult. When building a service on my own, I feel like I’m constantly switching back and forth between the developer and user personas. That’s really tough.
And lately, I’ve been constantly realizing just how valuable user feedback is. Even a 1-star rating is truly precious.&lt;/p&gt;
&lt;h2&gt;Reading.&lt;/h2&gt;
&lt;p&gt;Influenced by &lt;a href=&quot;#heo-gan-min&quot;&gt;Heo Gan-min&lt;/a&gt; (or more precisely, Editor Kim Min-kyung), I’ve resumed reading, something I’d been putting off. Perhaps because the content focuses on reading and culture, listening to Editor Kim’s stories quietly makes me gradually feel the urge to pick up a book. Recently, I attended a [podcast](https://podcasts.apple.com/us/podcast/1-27-%ED%99%94-%ED%8E%B8%EC%A7%91%EC%9E%90%EC%9D%98-%EB%B0%A9-%EB%B2%84%EC%A7%80%EB%8B%88%EC%95%84-%EC%9A%B8%ED%94%84-How to Use It - With a Spoon-ED%8E%B8%EC%A7%91%EC%9E%90-%EC%9C%A0%EC%83%81%ED%9B%88-%ED%8E%B8%EC%A7%91%EC%9E%90/id1811246527?i=1000746927301), I was persuaded to buy two of her books. &lt;code&gt;&amp;lt;The Essential Virginia Woolf&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Mrs. Dalloway&amp;gt;&lt;/code&gt;. I started reading them yesterday, and they’re interesting. As expected, I prefer novels to essays. And I like novels because they let me experience lives I haven’t lived and feel like I’m stepping into and out of someone else’s mind. Learning about things I’ve never experienced myself.&lt;/p&gt;
&lt;p&gt;Life has a certain inertia. Reading like this makes me want to write now. Wandering aimlessly on YouTube, I came across editor Kim Min-kyung... saw Heo Gan-min... started reading... and wrote a post on my blog... lol
I really do just go with the flow. But then again, what’s wrong with that?&lt;/p&gt;
&lt;h2&gt;The U.S.&lt;/h2&gt;
&lt;p&gt;I spent two months in the U.S. earlier this year. I saw and felt so much that I wanted to organize my thoughts on my blog, but I just couldn’t find the energy to write, so I kept putting it off until the first half of the year was over. I’ll definitely write it down in the second half of the year. For my own sake.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;After seeing &lt;a href=&quot;https://github.com/tw93&quot;&gt;My Favorite Developer&lt;/a&gt; do a weekly retrospective, I wanted to try it too, so I started. I plan to do my best to post consistently.&lt;/p&gt;
</content:encoded><category>weekly</category><author>Jinmu Go</author></item><item><title>Week 22 - Food Steward</title><link>https://jinmugo.com/en/weekly/2026-W22/</link><guid isPermaLink="true">https://jinmugo.com/en/weekly/2026-W22/</guid><description>Notes on a 10 km run and swimming, a fast-growing nasturtium, CKA study, LeetCode, and a Hermes Agent personal assistant setup.</description><pubDate>Wed, 27 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Workout Log&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;![[2026-W22-1780229056414.webp]]
![[2026-W22-1780229056415.webp]]
![[2026-W22-1780229056416.webp]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This week, I ran 10 km once, but my legs felt a bit strained, so I switched to swimming afterward. The weather has been perfect for running lately, so I was happy while running the 10km. I really do love running.&lt;/p&gt;
&lt;p&gt;When I first learned to swim, I used to enjoy it no matter how much I did, but these days, swimming isn’t that much fun anymore. It’s just a good workout for when it’s hot outside. Still, it has so many benefits that I enjoy doing it. (It’s relatively easy on the joints, I can hop in and out of the pool after a shower, and it’s a cool way to exercise when it’s too hot in the summer, etc.)&lt;/p&gt;
&lt;h2&gt;Honeysuckle&lt;/h2&gt;
&lt;p&gt;I’m growing a plant for the first time in my life. Its name is &lt;a href=&quot;https://www.google.com/search?q=%ED%95%9C%EB%A0%A8%ED%99%94&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot;&gt;Hibiscus&lt;/a&gt;. I brought it home when I visited a botanical garden. The only reason I chose this one is because its orange petals are pretty. I have a particular fondness for orange flowers.&lt;/p&gt;
&lt;p&gt;But this little friend is growing at an extraordinary rate. Even though it gets plenty of sunlight, I’ve never seen a plant grow this much from one day to the next. I wonder if other flowers and plants are like this too. It’s a plant that really makes growing it fun. It’s growing so well that I’m wondering if I should move it to a bigger pot.&lt;/p&gt;
&lt;p&gt;I’ve heard the petals are edible, but… hmm… for some reason, I don’t feel like eating them. I don’t think they’d taste good either.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![[2026-W22-1780232300734.webp]]
![[2026-W22-1780232300728.webp]]
![[2026-W22-1780232774070.webp]]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;CKA&lt;/h2&gt;
&lt;p&gt;I’ve started studying for the CKA and CKAD certifications I purchased during last year’s Cyber Monday. I’m planning to spend a total of three months preparing for them: two months for CKA and one month for CKAD.&lt;/p&gt;
&lt;p&gt;I plan to spend about two weeks taking a well-known CKA course, and after that, I’ll prepare by doing hands-on practice. Consistently. I won’t try to absorb all the knowledge at once; instead, I’ll acquire it slowly. Since I tend to be overly ambitious, I need to consciously remind myself of this so I can digest the knowledge gradually.&lt;/p&gt;
&lt;h2&gt;LeetCode&lt;/h2&gt;
&lt;p&gt;I recently started working on algorithms again. As AI-driven code generation has become mainstream, the amount of time I spend writing code myself has decreased significantly, but I’m rediscovering the joy of writing code from scratch that I had forgotten. Also, for some reason, when I start my day by solving algorithms, I feel like my brain is working a little better. It feels like my brain is warming up.&lt;/p&gt;
&lt;p&gt;I’m trying to solve at least one problem a day, and if I have the time, I plan to participate in the weekly contests as well.&lt;/p&gt;
&lt;h2&gt;Hermes Agent&lt;/h2&gt;
&lt;p&gt;I’ve built my own “personal assistant infrastructure” using Hermes Agent, Obsidian, and Syncthing. What I like most is that Syncthing lets me collaborate with a remote Hermes Agent by viewing each other’s edited Markdown files in real time. I should write a blog post about how I set this up.&lt;/p&gt;
</content:encoded><category>weekly</category><author>Jinmu Go</author></item><item><title>Week 23 - Nanchun</title><link>https://jinmugo.com/en/weekly/2026-W23/</link><guid isPermaLink="true">https://jinmugo.com/en/weekly/2026-W23/</guid><description>A week of recovering from a stomach bug, watching Stranger Things, finding Google&apos;s Easter egg, and trying to find direction at the end of spring.</description><pubDate>Sun, 07 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Workout Log&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;![[2026-W23-1780834295813.webp]]
![[2026-W23-1780834295815.webp]]
![[2026-W23-1780834295814.webp]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The weather was cool for June. I don’t think I went outside much around this time last year because it was so hot. Starting this Friday, I suddenly came down with an upset stomach, so I took it easy on Saturday and Sunday. On Saturday, when it first hit, I spent the whole day in complete agony. On Sunday, I was able to move around a bit, so I went for a run.&lt;/p&gt;
&lt;p&gt;It doesn’t seem like I’m that sick, but this is the first time I’ve had such a severe stomach bug, so I was a bit flustered. Even now, as I’m writing this, I’m still feeling a little pain. I hope I get better soon. Being sick really isn’t fun. Health is the best.&lt;/p&gt;
&lt;h2&gt;Stranger Things&lt;/h2&gt;
&lt;p&gt;While I was sick and lying in bed on Saturday and Sunday, I watched a lot of Stranger Things on Netflix. There are plenty of dramas out there, but right now, nothing else really suits my taste. Though I guess watching too much of it is a problem in itself.&lt;/p&gt;
&lt;p&gt;If you’re looking for a show to watch these days or need something to keep you company while eating, I recommend Stranger Things. Hmm… Come to think of it, I wouldn’t recommend watching it while eating if you have a weak stomach. There are so many bizarre scenes. If you can handle that, it should be fine.&lt;/p&gt;
&lt;p&gt;Also, I just found out that if you type “Stranger Things” into Google, a die appears below the search bar. If you click it, the entire search bar flips upside down. It’s a fun Google Easter egg.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![[2026-W23-1780836624287.webp]]
![[2026-W23-1780836644299.webp]]
![[2026-W23-1780836651877.webp]]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Late Spring&lt;/h2&gt;
&lt;p&gt;Spring seems to have passed, but since it still feels like the tail end of spring, I decided to use this title. These days are truly dizzying. I really can’t tell how things will unfold from here. It’s not like things were any different before, but right now, I’m even more at a loss. Where will I drift? Where will the ground beneath my feet lead me?&lt;/p&gt;
&lt;p&gt;Still, I have to move forward somewhere—I need to find my direction!&lt;/p&gt;
</content:encoded><category>weekly</category><author>Jinmu Go</author></item></channel></rss>