<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>My Little Blog</title><link>https://www.parkerchenca.com/</link><description>Recent content on My Little Blog</description><generator>Hugo</generator><language>en-us</language><copyright>Parker Chen</copyright><lastBuildDate>Thu, 10 Sep 2026 13:00:00 +0000</lastBuildDate><atom:link href="https://www.parkerchenca.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Migrating to Hugo</title><link>https://www.parkerchenca.com/tech/migrating-to-hugo/</link><pubDate>Thu, 10 Sep 2026 13:00:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/migrating-to-hugo/</guid><description>Why NotionNext had to go, and few problems Hugo handed me on the way in.</description><content:encoded><![CDATA[<p>I moved my blog to Hugo. I&rsquo;ve had some free time in the gap between
graduating and landing a job, so I finally got around to something I&rsquo;d been
putting off for a while.</p>
<h2 id="why-migrate-at-all">Why migrate at all</h2>
<p>A few things pushed me toward it. A couple of years into the Computer
Programming and Analysis program, I&rsquo;d seen enough tools and tradeoffs that
&ldquo;run a lighter stack&rdquo; stopped being an abstract idea and turned into an
actual plan. <a href="https://github.com/notionnext-org/NotionNext">NotionNext</a> is a
good project. I&rsquo;ll get into why it stopped working for me, but it&rsquo;s more machinery than a
personal blog needs.</p>
<p>I&rsquo;d also run out of excuses not to touch it. One of my rules is: if it works, don&rsquo;t
touch it, and that&rsquo;s exactly why this sat on my todo list for so long.
But &ldquo;I don&rsquo;t fully understand web app internals yet&rdquo; was not true
for me anymore, and once that excuse is gone, all that&rsquo;s left is a task
I&rsquo;m avoiding.</p>
<p>And practically, between graduation and the next job I have more free time
than I&rsquo;ll have again for a while, so it made sense to sit with my notes and
actually figure out what I&rsquo;d learned. Getting back into regular blogging
needed a platform I&rsquo;d actually want to open.</p>
<p>I also looked at Hexo and Astro. The short version of why Hugo won is in
<a href="/tech/building-this-blog/">Building This Blog</a>: it comes down to how content
maps to URLs and how each one handles Org-mode.</p>
<p>The longer version is that this year I went through IDEA, VS Code, Neovim, and Emacs for different kinds
of work. IDEA is still my favorite for Java: its indexing and language
support make everything else feel like it&rsquo;s guessing. VS Code is the
balanced choice once you&rsquo;re off Java or working on something large; the
ecosystem covers file browsing, Markdown rendering, and even reading a PDF
without leaving the editor. And since I live in a terminal (WSL as my main
environment, so I get fzf, rg, and the Linux tooling that things like Claude
Code supported first) right now, Neovim is hard to pass up: it&rsquo;s light, fast, and
everything stays on the keyboard.</p>
<p>None of that is actually why I picked Hugo, though. I picked Hugo because I
fell for <em>Emacs</em>. It&rsquo;s the first tool that gave me what &ldquo;one unified
environment&rdquo; actually means. The Org mode is the part I like most: think of
it as Markdown crossed with a Jupyter notebook. When I want code output
sitting inside my notes instead of copy-pasted from a terminal, Org is about
the best format for that. Hugo happens to parse Org natively, so the fit was
already there before I went looking for it.</p>
<h3 id="why-not-just-stay-on-notionnext">Why not just stay on NotionNext</h3>
<p>This is the part with real evidence behind it, not just preference:</p>
<ol>
<li>
<p>It&rsquo;s a React app with a long dependency chain.</p>
</li>
<li>
<p>It&rsquo;s hard-coupled to the Notion API. A major API update once took the
whole blog down in one shot, and there was nothing I could do about it on
my end.</p>
</li>
<li>
<p>Forking is the wrong shape for this. Maintaining my own fork meant every
upstream change was a potential merge conflict and a version-bump
decision I didn&rsquo;t want to make.</p>
</li>
<li>
<p>Error rates I never got to the bottom of. Vercel&rsquo;s dashboard would
occasionally show something like this:</p>
<figure>
       <img loading="lazy" src="high-error-rate.png"
            alt="Vercel observability panel showing a 58% error rate"/> <figcaption>
               <p>Vercel&rsquo;s own dashboard, mid outage.</p>
           </figcaption>
   </figure>

</li>
<li>
<p>The deployments themselves were flaky, on top of everything else. A run
of &ldquo;Updated&rdquo; deploys failing back to back on production isn&rsquo;t something
you want in your history:</p>
<figure>
       <img loading="lazy" src="deployment-errors.png"
            alt="A string of failed Vercel deployments"/> <figcaption>
               <p>A run of production deploys failing back to back.</p>
           </figcaption>
   </figure>

</li>
<li>
<p>React&rsquo;s CVE treadmill. Every so often there was a fresh CVE to patch that
had nothing to do with anything I&rsquo;d written:</p>
<figure>
       <img loading="lazy" src="cve-fix.png"
            alt="A commit titled &#39;Fix React Server Components CVE vulnerabilities&#39;"/> <figcaption>
               <p>A CVE patch that had nothing to do with anything I&rsquo;d written.</p>
           </figcaption>
   </figure>

</li>
</ol>
<p>None of that is exotic. It&rsquo;s just the cost of running someone else&rsquo;s React
app instead of a static site, and I&rsquo;d paid it long enough.</p>
<h2 id="how-i-migrated">How I migrated</h2>
<h3 id="getting-oriented">Getting oriented</h3>
<p>I started at Hugo&rsquo;s own site, found the themes gallery, and looked for
something that fit a personal, bilingual blog. PaperMod stood out: MIT
licensed, 13.9k GitHub stars, still getting updates, and the demo already
looked close to what I wanted without any customization.</p>
<figure>
    <img loading="lazy" src="hugo-themes.png"
         alt="Hugo&#39;s themes page showing the PaperMod theme"/> <figcaption>
            <p>PaperMod&rsquo;s listing in Hugo&rsquo;s theme gallery.</p>
        </figcaption>
</figure>

<p>From there it was the usual mix: reading the theme&rsquo;s own docs, skimming its
GitHub repo for how people actually configure it, and asking an AI assistant
questions that would&rsquo;ve otherwise cost an evening of trial and error, mostly
which config keys are current versus deprecated, and how Hugo&rsquo;s page bundles
are supposed to be laid out.</p>
<h3 id="actually-doing-it">Actually doing it</h3>
<p>The content move itself was mechanical: 45 posts pulled out of a Notion
export, cleaned up, and dropped into <code>content/</code>. The interesting part was
everything that broke after the content was in place, and none of it showed
up until I actually tried to use the feature.</p>
<h4 id="one-issue-oversized-record-failed-the-whole-deploy">One Issue: oversized record failed the whole deploy</h4>
<p>My Algolia push script truncates each post&rsquo;s content to stay under Algolia&rsquo;s
10KB per-record limit, but I&rsquo;d only truncated <code>content</code>, not <code>summary</code>. Hugo
builds an automatic summary by grabbing whole content blocks, and one post
that opened with a long block produced an 11KB summary. Algolia rejected the
record, the push script exited non-zero, and that failed the entire Vercel
build: not a partial deploy with one missing search result, a hard stop.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="s">&#34;summary&#34;</span><span class="w"> </span><span class="p">(.</span><span class="nx">Summary</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">plainify</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">truncate</span><span class="w"> </span><span class="mi">300</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">htmlUnescape</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">htmlUnescape</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><h3 id="cutting-over">Cutting over</h3>
<p>The old blog was still live on Vercel, wired to <a href="https://www.parkerchenca.com">www.parkerchenca.com</a> and
parkerchenca.com. First I paused that project.</p>
<p>Then it was straightforward: pull the domain off the old project, import the
new repo as its own Vercel project, add the environment variables, and point
the domain back at the new one. Vercel won&rsquo;t let the same domain sit on two
projects at once, so the order matters.</p>
<p>Comments were the last piece: giscus needed the repository to be public with
GitHub Discussions turned on and its own GitHub App installed before it would
actually render anything.</p>
<p>And then, boom, it was done. Simpler than I expected, and the environment
variables even came out to about half of what NotionNext needed.</p>
<h3 id="where-that-leaves-things">Where that leaves things</h3>
<p>The blog is live, search works, comments work (I think the light/dark toggle
also flips the comment widget now, but I haven&rsquo;t actually tested it in a
browser myself. If you&rsquo;ve read this far, give it a try and tell me in the
comments below ;D ).</p>
<h2 id="useful-links">Useful links</h2>
<p>Hugo:</p>
<ul>
<li><a href="https://github.com/adityatelange/hugo-PaperMod">https://github.com/adityatelange/hugo-PaperMod</a></li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/wiki">https://github.com/adityatelange/hugo-PaperMod/wiki</a></li>
</ul>
<p>My Blog:</p>
<ul>
<li><a href="https://github.com/BHChen24/MyLittleBlog-Hugo/">https://github.com/BHChen24/MyLittleBlog-Hugo/</a></li>
</ul>
]]></content:encoded></item><item><title>OSD600 Release 0.4 Part 3 - Reflecting</title><link>https://www.parkerchenca.com/osd600/release-0-4-part-3-reflecting/</link><pubDate>Thu, 10 Sep 2026 11:50:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-4-part-3-reflecting/</guid><description>Wrapping it all together</description><content:encoded><![CDATA[<h2 id="intro">Intro</h2>
<p>My original goal for Release 0.4 was to contribute real code to a large open-source project related to finance. I completed that goal by working on Actual Budget, which is a fairly big project with around 23k stars.</p>
<h3 id="thoughts-about-the-future">Thoughts About the Future</h3>
<hr>
<p>Now that I understand the workflow better, I hope I can eventually try adding a feature or modifying core code in a large codebase. I’m also paying attention to bigger finance-related libraries such as QuantLib, and maybe one day I will be able to contribute there as well.</p>
<p>Overall, I would say I accomplished what I wanted for this release — just not as fully as I expected. But it’s still a good start.</p>
<h3 id="how-i-worked-through-the-problem">How I Worked Through the Problem</h3>
<hr>
<p>Most of my technical work is understanding the project’s structure and figuring out how to safely fix the type issue. One important thing I learned was that the <code>.d.ts</code> files inside <code>/node_modules/@actual-app/...</code> are not the source code, even though ESLint and TypeScript errors pointed me there.</p>
<p><img alt="*.d.ts files for the issue desc" loading="lazy" src="/osd600/release-0-4-part-3-reflecting/Screenshot_2025-12-12_at_15.54.17.png"></p>
<p>*.d.ts files for the issue desc</p>
<p>These files only describe the types, so the real fix needed to be applied in the actual source files with the same paths (not totally same).</p>
<p><img alt="… And their corresponding original files" loading="lazy" src="/osd600/release-0-4-part-3-reflecting/Screenshot_2025-12-12_at_15.47.13.png"></p>
<p>… And their corresponding original files</p>
<p>Another useful technique I learned was compiling files directly using <code>tsc</code>. By compiling only the files I changed, I could quickly check whether the error was fixed.</p>
<p>But since I had to temporarily update the config to include my test files, it was easy to break something by accident. In this case, I relied on Git to get rid of all temp files and keep the repo clean before submitting the changes (To be honest, creating a totally new test branch is another good idea).</p>
<p>I must mention that, the “fork first, then work separately” workflow we learned in class this semester did help me a looooot for managing my chaotic developing process.</p>
<h3 id="community-communication-and-the-open-source-mindset">Community, Communication, and the Open Source Mindset</h3>
<hr>
<p>After watching my classmates’ presentations, I realized that mastering a specific language is not the main requirement for open-source contribution. The real skill is always the communication: reading existing discussions, following instructions, asking questions when unsure, and respecting the time of maintainers.</p>
<p>Large projects usually have clear contributing guides, and Actual Budget is no exception. Their documentation explains workflow, expectations, and review rules in detail. As contributors, our responsibility is to follow these instructions first before doing anything else. Good communication keeps the whole project running smoothly; ignoring guidelines only creates extra work for others.</p>
<p>My PR also helped me experience the interaction between contributors and automated tools like Copilot, Coderabbitai, and many other review bots. They gave suggestions and asked for tests. Sometimes I felt a bit frustrated that I couldn’t discuss things with a real human; however, if I can solve the issue with bots alone, I guess it means I did a pretty good job, right…?</p>
<p>Overall, this release helped me understand more about two key concepts of the open source community: communication and respect.</p>
<p>I really enjoy the friendly and efficient communication among the contributors.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.4 Part 2 - Processing</title><link>https://www.parkerchenca.com/osd600/release-0-4-part-2-processing/</link><pubDate>Thu, 10 Sep 2026 11:49:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-4-part-2-processing/</guid><description>Pushing things forward</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Me working with a big project… Wait, me?</p>
</blockquote>
<h2 id="starting-the-contribution">Starting the Contribution</h2>
<hr>
<p>This week I finally moved from planning into actually contributing. I decided to work on <strong>Actual Budget</strong> again, and honestly, I was kinda nervous because this repository has 23.6k stars, real users, and an active core team.</p>
<p>I chose a TypeScript issue related to incompatible type definitions</p>
<p>(<a href="https://github.com/actualbudget/actual/issues/6290">https://github.com/actualbudget/actual/issues/6290</a>).</p>
<p>In short, the <code>Query</code> type was missing a few methods and caused type errors inside the API package.</p>
<p>My PR is small and touches only a few lines of code (PR: <a href="https://github.com/actualbudget/actual/pull/6331">https://github.com/actualbudget/actual/pull/6331</a>). The challenge was not writing the code only, but understanding what the project expected from contributors.</p>
<h3 id="understanding-the-project-and-the-rules">Understanding the Project and the Rules</h3>
<hr>
<p>Before writing anything, I spent most of my time reading the project structure and the Contributing guide. Actual Budget has an entire website explaining how to participate:</p>
<p><a href="https://actualbudget.org/docs/contributing/">https://actualbudget.org/docs/contributing/</a></p>
<p>Compared to our previous workflows, the overall process is similar — fork repo, create branch, implement change, send PR. However, the attitude and expectations are much more formal.</p>
<p>The contributing guide explains:</p>
<ul>
<li>development workflow</li>
<li>expectations for PR quality</li>
<li>how reviews work</li>
<li>and, very directly, that not every PR will be accepted</li>
</ul>
<blockquote>
<p>“We aren’t going to take every single little change. Don’t be offended if we close your PR…”</p>
</blockquote>
<p>So even for a small fix like mine, discussion might still be required, and reviewers could ask for adjustments. It’s more serious, but also very professional.</p>
<p>In addition, I got in touch with <code>yarn</code> in this project, and the project has a set of commands to generate a release note instead of describing PR on GitHub.</p>
<h3 id="the-pr-experience">The PR Experience</h3>
<hr>
<p>After pushing my code, I first marked it with <code>[WIP]</code>. Soon after, Copilot automatically reviewed the PR and suggested writing tests. That’s kind of strange because when I checked the file, I found there were no dedicated tests at all for that file, so I asked the question directly inside the discussion and waited for a reviewer to reply.</p>
<p>When I removed <code>[WIP]</code>, another automated reviewer (coderabbitai) appeared, plus almost 30 checks waiting to finish. Seeing that number made me feel how large and complex this project really is.</p>
<p>So far, the review and discussion are still ongoing.</p>
<h3 id="final-thoughts">Final Thoughts</h3>
<hr>
<p>Even though this PR is small, the experience means huge for me. I got to know about how large open-source projects manage quality and how serious review standards can be.</p>
<p>I also feel more confident contributing to large projects now. I’m planning to share more details and personal reflections during Friday’s meeting, and hopefully continue contributing after Release 0.4.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.4 Part 1 - Planning</title><link>https://www.parkerchenca.com/osd600/release-0-4-part-1-planning/</link><pubDate>Thu, 10 Sep 2026 11:48:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-4-part-1-planning/</guid><description>Scheduling things out</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Tough week, and it will get tougher</p>
</blockquote>
<h2 id="planning-for-the-release-04">Planning for the release 0.4</h2>
<p>Last week, we wrapped up some final tasks for Release 0.3, and now I’m officially moving into the work for Release 0.4. I mentioned earlier that I was still waiting for my PR for Release 0.3 to be merged. Fortunately, right after the lecture, someone from Opsimate finally reviewed my changes and gave me feedback. The response time was a bit slow, but at least things are moving again.</p>
<p>The real issue, however, is the schedule. The end of the semester is approaching, and last week I was completely occupied with assignments from other courses. Because of that, I didn’t spend as much time exploring Release 0.4 as I had hoped.</p>
<p>The good news is that during Release 0.3, I had already identified a few projects I really wanted to contribute to: <a href="https://www.parkerchenca.com/en/article/2aaf0ccf-d7f8-8015-91e1-e557e20be6b3">My last post</a>. I also spent some time understanding their codebases, so I’m not starting from zero. I’ll talk about those projects below.</p>
<p>My plan is to clear out the most urgent schoolwork first, then fully commit myself to Release 0.4.</p>
<h3 id="microsoft-qlib"><a href="https://github.com/microsoft/qlib"><strong>Microsoft Qlib</strong></a></h3>
<p>I already finished setting up the environment using <code>pyenv</code> and <code>uv</code>, which allows me to manage Python dependencies very cleanly. I also prepared the example dataset used in the project.</p>
<p>My next step is to go through the latest issues on their GitHub repo and see if there are any that interest me or are suitable for my skill level. Once I choose an issue, I can start analyzing the relevant parts of the code.</p>
<p>I don’t intend to fully understand the entire codebase, because Qlib is large and complex. Instead, I plan to learn the sections that are directly related to the issue I want to work on.</p>
<h3 id="actual-budget"><a href="https://github.com/actualbudget/actual"><strong>Actual Budget</strong></a></h3>
<p>When I was reading the code earlier, I actually found an approach for solving this issue: <a href="https://github.com/actualbudget/actual/issues/6149"><strong>https://github.com/actualbudget/actual/issues/6149</strong></a></p>
<p>However, the problem mainly involves the UI, and the fix probably requires only around ten lines of code(In fact, the existing PR for this issue modifies fewer than 20 lines.) Because of that, I eventually decided not to work on this issue, since it feels too small for Release 0.3.</p>
<p>My next step is to continue exploring the parts of Actual Budget’s codebase that I already understand and look for issues that are more meaningful to contribute to.</p>
<p>One thing I realized while reading the code is that in a well‑designed project, adding a new feature—even a large one—doesn’t necessarily require changing many lines of code. The architecture handles most of the complexity. For an assignment, this might make the contribution look “too small on the surface,” but the real difficulty lies in reading and understanding the existing code.</p>
<h3 id="-summary">🧳 Summary</h3>
<p>In my current plan for Release 0.4, I expect to focus mainly on these two projects. The most difficult part for me right now isn’t the code itself, but managing my time during this extremely busy part of the semester.</p>
<p>I hope everyone in the course has a smooth development process, and I’ll try my best to push forward as well.</p>
]]></content:encoded></item><item><title>OSD600 Lab 9</title><link>https://www.parkerchenca.com/osd600/lab-9/</link><pubDate>Thu, 10 Sep 2026 11:47:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-9/</guid><description>&lt;blockquote&gt;
&lt;p&gt;🔔 &lt;strong&gt;Prelude:&lt;/strong&gt;
Rocket lift off&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="answering-main-lab-questions"&gt;Answering Main Lab Questions&lt;/h2&gt;
&lt;p&gt;Originally I had a &lt;strong&gt;reflection&lt;/strong&gt; section for this blog, but my Professor provides some wonderful questions for me to share my experience and thoughts, so, my reflection has been melted into my answers. I hope you can find useful information directly in there.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Which release tool and package registry did you choose? Provide links to everything you mention.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go has it’s unique release system — basically, if I init my module locally, push to the GitHub, have a right git tag version, and finally click the “Request” on &lt;a href="https://pkg.go.dev/example.com/my/module"&gt;&lt;code&gt;https://pkg.go.dev/example.com/my/module&lt;/code&gt;&lt;/a&gt; … then, done, I don’t need to handle rest things, the module will be indexed on the official module platform, and anyone should be able to &lt;code&gt;go install&lt;/code&gt; my module. So convenience.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What was the process for creating a release? Be detailed so that other developers could read your blog and get some idea how to do the same.&lt;/strong&gt;&lt;/p&gt;</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Rocket lift off</p>
</blockquote>
<h2 id="answering-main-lab-questions">Answering Main Lab Questions</h2>
<p>Originally I had a <strong>reflection</strong> section for this blog, but my Professor provides some wonderful questions for me to share my experience and thoughts, so, my reflection has been melted into my answers. I hope you can find useful information directly in there.</p>
<ul>
<li>
<p><strong>Which release tool and package registry did you choose? Provide links to everything you mention.</strong></p>
<ul>
<li>Go has it’s unique release system — basically, if I init my module locally, push to the GitHub, have a right git tag version, and finally click the “Request” on <a href="https://pkg.go.dev/example.com/my/module"><code>https://pkg.go.dev/example.com/my/module</code></a> … then, done, I don’t need to handle rest things, the module will be indexed on the official module platform, and anyone should be able to <code>go install</code> my module. So convenience.</li>
</ul>
</li>
<li>
<p><strong>What was the process for creating a release? Be detailed so that other developers could read your blog and get some idea how to do the same.</strong></p>
<ul>
<li>Ok, assume that you already have a “ready-to-go” codebase (you cannot release empty folder)</li>
<li>Then, you should use <code>git tag</code> related commands for tagging you current commit (Use <code>git tag --help</code> for help)</li>
<li>Next, you should push your commit to GitHub, maybe you have already done that, so, you should <strong>push your tag</strong> separately to GitHub</li>
<li>Don’t forget to change your documentation… I used to notice that my release still shows <strong>v0.0.1</strong> for the version flag, which means I have to repeat my work again (depressedly).</li>
<li>Finally, you can release your package. I used <strong>Go</strong>, and put some useful links in the <strong>Reference</strong> section. If you are also using GO, them can help you make your way.</li>
</ul>
</li>
<li>
<p><strong>What did you learn while doing your release? Did you have any &ldquo;aha!&rdquo; moments or get stuck?</strong></p>
<ul>
<li>A lot of “aha!” moments, actually.</li>
<li>Go’s release workflow feels almost suspiciously simple—so simple that sometimes I overthought things.</li>
<li>The biggest challenge wasn’t complexity but the danger of skipping steps because the process looked too easy.</li>
<li>You can find more of my “aha!” moments in the detailed experience I describe below.</li>
</ul>
</li>
<li>
<p><strong>How much did you have to alter your code, files, build, etc. to use the chosen package format and registry?</strong></p>
<ul>
<li>I didn’t need to change my code structure at all (But actually, I still need to change the documents).</li>
<li>Go’s build system is easy, clean and straightforward. I think this is one of the reasons many developers love Go — compared to languages like C++, incremental builds and direct code fetching “just work.” (Disclaimer: I also really like C++.)</li>
<li>One thing to be careful about is that git tags <strong>must</strong> follow the <strong><code>vX.X.X</code></strong> format, such as <strong><code>v1.0.1</code></strong>. Otherwise, the Go package platform may fail to recognize the version or cause unexpected issues.</li>
</ul>
</li>
<li>
<p><strong>How did the User Testing session with your partner go? Describe what it was like, where they got stuck, and how you corrected the problems.</strong></p>
<ul>
<li>Before the session, I tested installation myself on my Raspberry Pi.</li>
<li>Interestingly, because my package URL is <strong><code>https://pkg.go.dev/github.com/BHChen24/repo2context</code></strong>, the default installed binary is named <strong><code>repo2context</code></strong>, not the short alias <strong><code>r2c</code></strong> that I used throughout my documentation.</li>
<li>This confused both me at first — I couldn’t find the installed executable because I was searching for <strong><code>r2c</code></strong>.</li>
<li>To avoid further confusion, I updated my <strong>README</strong> to explicitly mention this and show how to rename the binary if users prefer a shorter command.</li>
<li>Still waiting for feedbacks from my partners</li>
</ul>
</li>
<li>
<p><strong>How do users install and use your project now that it has been released? Provide links and some instructions.</strong></p>
<ul>
<li>I have provided full installation instructions in my README:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## Installation
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Prerequisites
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> [<span class="nt">Go</span>](<span class="na">https://go.dev/</span>) installed on your system
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Quick Install
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">```bash
</span></span><span class="line"><span class="cl">go install github.com/BHChen24/repo2context<span class="ni">@latest</span>
</span></span></code></pre></div><p>This installs the binary as <code>repo2context</code> to your <code>$GOPATH/bin</code> (or <code>$HOME/go/bin</code> by default).</p>
<p><strong>Add Go bin to PATH</strong> (if not already configured):</p>
<p>Linux/macOS:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># For bash</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;export PATH=$PATH:$HOME/go/bin&#39;</span> &gt;&gt; ~/.bashrc <span class="o">&amp;&amp;</span> <span class="nb">source</span> ~/.bashrc
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># For zsh</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s1">&#39;export PATH=$PATH:$HOME/go/bin&#39;</span> &gt;&gt; ~/.zshrc <span class="o">&amp;&amp;</span> <span class="nb">source</span> ~/.zshrc
</span></span></code></pre></div><p>Windows (PowerShell as Administrator):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="p">[</span><span class="no">Environment</span><span class="p">]::</span><span class="n">SetEnvironmentVariable</span><span class="p">(</span><span class="s2">&#34;Path&#34;</span><span class="p">,</span> <span class="nv">$env:Path</span> <span class="p">+</span> <span class="s2">&#34;;</span><span class="nv">$env:USERPROFILE</span><span class="s2">\go\bin&#34;</span><span class="p">,</span> <span class="s2">&#34;User&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>Then restart your terminal.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Verify installation</span>
</span></span><span class="line"><span class="cl">repo2context --version
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># (Optional) Rename to shorter command</span>
</span></span><span class="line"><span class="cl">mv ~/go/bin/repo2context ~/go/bin/r2c
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">I found once my app is released on the go pkg platform, all these instructions also appear on the home page, which is really cool and convenient. I put it again here for you to quickly navigate: [https://pkg.go.dev/github.com/BHChen24/repo2context](https://pkg.go.dev/github.com/BHChen24/repo2context)
</span></span></code></pre></div></li>
</ul>
<h3 id="references"><strong>References</strong></h3>
<ul>
<li><a href="https://pkg.go.dev/about#adding-a-package">https://pkg.go.dev/about#adding-a-package</a></li>
<li><a href="https://semver.org/">https://semver.org/</a></li>
</ul>
]]></content:encoded></item><item><title>OSD600 Release 0.3 Part 2 - Fixing bugs</title><link>https://www.parkerchenca.com/osd600/release-0-3-part-2-fixing-bugs/</link><pubDate>Thu, 10 Sep 2026 11:46:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-3-part-2-fixing-bugs/</guid><description>Oops, I’m not meaning to discover them ..</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Bugs in the middle of the way</p>
</blockquote>
<h2 id="opsimate-bugs-fixing">OpsiMate bugs fixing</h2>
<p>During the development of the new Coralogix integration, I ended up discovering two UI bugs — because of course things like this always happen, right?</p>
<ol>
<li>The first issue was a missing icon. This one was extremely small: a one‑line fix in a single file. Honestly the PR felt almost too tiny.</li>
<li>Fortunately, another bug appeared at exactly the right time. This one involved a UI element that refused to trigger properly, which required a bit more investigation and work.</li>
</ol>
<h3 id="missing-dog">Missing dog</h3>
<ol>
<li>
<p>In my first blog post, I mentioned that OpsiMate includes a DataDog integration. Ironically, the dog went missing</p>
<p><img alt="Where is the dog?" loading="lazy" src="/osd600/release-0-3-part-2-fixing-bugs/Screenshot_2025-11-20_224841.png"></p>
<p>Where is the dog?</p>
</li>
<li>
<p>I attached the screenshot directly to the issue. It more or less explains the entire situation by itself <a href="https://github.com/OpsiMate/OpsiMate/issues/557">https://github.com/OpsiMate/OpsiMate/issues/557</a>.</p>
</li>
<li>
<p>I wasn’t sure if I had to follow the full issue template… describing such a simple visual bug felt also a little bit painful.</p>
</li>
<li>
<p>The fix was straightforward, and again, a screenshot was enough to show the completed result: <a href="https://github.com/OpsiMate/OpsiMate/pull/560">https://github.com/OpsiMate/OpsiMate/pull/560</a></p>
<p><img alt="Doggy is back!" loading="lazy" src="/osd600/release-0-3-part-2-fixing-bugs/Screenshot_2025-11-21_014414.png"></p>
<p>Doggy is back!</p>
</li>
</ol>
<h3 id="indifference-button">Indifference button</h3>
<ol>
<li>
<p>The other issue was a button labeled “Add Provider” that refused to open the sidebar.</p>
</li>
<li>
<p>While researching good tools for recording UI interactions, I discovered ScreenToGif: <a href="https://github.com/NickeManarin/ScreenToGif">https://github.com/NickeManarin/ScreenToGif</a> . It turned out to be incredibly useful, and I used it to record a small gif video and attach it to the issue.</p>
<p><img alt="So easy for using" loading="lazy" src="/osd600/release-0-3-part-2-fixing-bugs/image.png"></p>
<p>So easy for using</p>
</li>
<li>
<p>You can see the lively demonstration right in the issue: <a href="https://github.com/OpsiMate/OpsiMate/issues/558">https://github.com/OpsiMate/OpsiMate/issues/558</a>. It’s one of those situations that is very hard to explain clearly with text alone.</p>
<p><img alt="Wow I can also insert it here!" loading="lazy" src="/osd600/release-0-3-part-2-fixing-bugs/bug.gif"></p>
<p>Wow I can also insert it here!</p>
</li>
<li>
<p>The root cause was improper state management. Once I identified which component and function were supposed to be triggered, the fix itself was not too difficult.</p>
</li>
</ol>
<h3 id="reflects">Reflects</h3>
<p>Overall, even when you focus on a single PR, bugs still have a way of appearing continuously (sadly). There’s never a shortage of issues to work on — you don’t have to worry about “running out” of them.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.3 Part 2 - Adding features</title><link>https://www.parkerchenca.com/osd600/release-0-3-part-2-adding-features/</link><pubDate>Thu, 10 Sep 2026 11:45:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-3-part-2-adding-features/</guid><description>LEGOING</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
API document reading — totally as hell</p>
</blockquote>
<h2 id="coralogix-integration">Coralogix Integration</h2>
<h3 id="what-is-it">What is it?</h3>
<p>According to the official description, Coralogix provides “real-time insights and trend analysis for logs, metrics, and security data with no reliance on storage or indexing.”</p>
<p>In simpler terms, it is essentially a real-time server monitoring and observability service. Coralogix helps track logs, visualize metrics, and detect anomalies without requiring developers to manage complex storage systems. For projects with active deployments, this kind of integration makes debugging and performance monitoring much easier.</p>
<p><img alt="Coralogix’s Main Dashboard" loading="lazy" src="/osd600/release-0-3-part-2-adding-features/Screenshot_2025-11-21_164213.png"></p>
<p>Coralogix’s Main Dashboard</p>
<p>My main task is to first fetch all the dashboards’ information to support further features.</p>
<h3 id="challenges">Challenges</h3>
<ol>
<li>
<p>Reading the API documentation turned out to be much harder than I expected. As shown in the screenshot：</p>
<p><img alt="API Docs" loading="lazy" src="/osd600/release-0-3-part-2-adding-features/Screenshot_2025-11-21_164425.png"></p>
<p>API Docs</p>
<p>The example on the API usage page points to <strong><code>https://api.coralogix.com/</code></strong>. However, when I used this endpoint, I didn’t receive any meaningful response—only an API key permission error.</p>
</li>
<li>
<p>I went back to the dashboard and expanded my API key permissions all the way to the admin, but the error still appeared. That was when things started feeling really strange.</p>
</li>
<li>
<p>Since the issue clearly wasn’t about permissions, I began to suspect the endpoint itself. It didn’t make much sense that <strong>everyone</strong> would use the same entry point. So I spent a long time digging around the documentation… and eventually found the endpoint control page: <a href="https://coralogix.com/docs/integrations/coralogix-endpoints/"><strong>https://coralogix.com/docs/integrations/coralogix-endpoints/</strong></a></p>
<p><img alt="End Point demonstration" loading="lazy" src="/osd600/release-0-3-part-2-adding-features/Screenshot_2025-11-21_164248.png"></p>
<p>End Point demonstration</p>
</li>
<li>
<p>I was a bit frustrated — why wasn’t this mentioned anywhere on the main API page? And because the service is still relatively new, there is almost no discussion online; even AI tools didn’t help much. Honestly, I think it was part luck and part persistence that led me to the correct page. Otherwise, I would have wasted much more time.</p>
</li>
<li>
<p>By the way… there are also outdated API references still visible in the docs</p>
<p><img alt="Huh?" loading="lazy" src="/osd600/release-0-3-part-2-adding-features/Screenshot_2025-11-21_164312.png"></p>
<p>Huh?</p>
<p>which makes things even more confusing.</p>
</li>
<li>
<p>Through this experience, I realized how important high-quality developer documentation is…</p>
</li>
</ol>
<h3 id="fixing">Fixing</h3>
<ol>
<li>
<p>To implement the new feature, I mostly referenced another integration in the project : <a href="https://github.com/OpsiMate/OpsiMate/blob/main/apps/server/src/bl/integrations/integration-connector/datadog-integration-connector.ts">https://github.com/OpsiMate/OpsiMate/blob/main/apps/server/src/bl/integrations/integration-connector/datadog-integration-connector.ts</a>.</p>
<p>Their implementation was very clean, so I could follow the structure and focus mainly on handling the data — the request and response parts.</p>
</li>
<li>
<p>And although the Coralogix documentation has some organization issues, the API page itself is straightforward. It clearly shows the response format, and the examples are easy to follow:</p>
<p><img alt="A clear API response" loading="lazy" src="/osd600/release-0-3-part-2-adding-features/Screenshot_2025-11-21_164435.png"></p>
<p>A clear API response</p>
<p>This made writing the actual code much easier.</p>
</li>
<li>
<p>Apart from the time I spent searching for the correct endpoint, the actual development process was quite enjoyable. Nothing beats the satisfaction of running a <code>curl</code> command and finally seeing the server return the correct data.</p>
</li>
</ol>
]]></content:encoded></item><item><title>OSD600 Release 0.3 Part 1</title><link>https://www.parkerchenca.com/osd600/release-0-3-part-1/</link><pubDate>Thu, 10 Sep 2026 11:44:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-3-part-1/</guid><description>Houston, we have a problem.</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I have a bad feeling about this: once again, I find myself stuck trying to choose the right project.</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<h3 id="still-wip">Still WIP</h3>
<p>At the end of this week, I haven’t submitted my first PR yet. Most of my time went into searching for a suitable open‑source project, and my plan is to update this post again after I finally publish my first PR.</p>
<p>Since I previously mentioned that I want to contribute to a repo related to <strong>$<em>finance</em>$</strong>🤑, I spent a good amount of time exploring that topic. Here are some projects currently on my list:</p>
<h3 id="ai-powered-investment-platform">AI-powered investment platform</h3>
<p><strong>Microsoft Qlib</strong> (<a href="https://github.com/microsoft/qlib"><strong>https://github.com/microsoft/qlib</strong></a>)</p>
<p><strong>Qlib</strong> describes itself as “an AI‑oriented quantitative investment platform,” but in simpler words, it’s a framework that provides data tools, modeling support, and workflow automation to help build AI‑driven quantitative trading strategies.</p>
<ul>
<li>I’m personally very interested in this project and have already started exploring it. The development activity is not bad — issues and PRs are still being handled as recently as this week.</li>
<li>It uses Python, has plenty of issues to choose from, focuses on a hot topic (AI), and the documentation is fairly complete.</li>
<li>But…I spent an entire afternoon debugging my Python environment. Absolutely terrifying.</li>
</ul>
<h3 id="opensource-banking-system">Open‑source banking system</h3>
<p><strong>Apache Fineract</strong> (<a href="https://github.com/apache/fineract"><strong>https://github.com/apache/fineract</strong></a>)</p>
<ul>
<li>This is an open‑source banking system written in Java. I feel that its tech stack aligns well with what employers in the industry expect. If I can learn its design principles and make meaningful contributions, it could be very helpful for my future job search.</li>
<li>However, the repo doesn’t have a typical Issues section, and its contribution rules seem quite different. I might need extra time to figure out how to get started.</li>
<li>Still, this is the project I’m currently most interested in.</li>
</ul>
<h3 id="personal-finance-app">Personal-finance app</h3>
<p><strong>Actual Budget</strong> (<a href="https://github.com/actualbudget/actual"><strong>https://github.com/actualbudget/actual</strong></a>)</p>
<ul>
<li>This personal finance platform is super active: around 30 PRs were handled within just a week, and it has around 23k stars. Clearly a very popular project.</li>
<li>It mainly uses TypeScript and focuses on “practical frontend” features. The demo isn’t such fancy, but the features look solid and well‑built.</li>
<li>It doesn’t feel “technically fancy” or groundbreaking, but it solves real problems — exactly the type of project I care about and would like to contribute to.</li>
</ul>
<h3 id="-summary">🧳 Summary</h3>
<p>Overall, I’m still in the process of selecting the right project and diving into the code, but I’m getting closer. Hopefully I can finally report back with my first PR on weekend.</p>
<h3 id="updates">Updates</h3>
<p>Over the past several days, a few things happened that changed the direction of my work.</p>
<ol>
<li>At first, I planned to continue exploring Qlib. However, when I tried to set up the environment, <strong><code>uv</code></strong> and <strong><code>pyenv</code></strong> ended up conflicting with each other again.</li>
<li>I spent additional time rebuilding a clean environment, but unexpectedly, Python packages started throwing compilation errors—some of them simply refused to build.</li>
<li>At that point, I felt I had already invested too much time just dealing with environment issues. So I decided to switch back to a project I’m more familiar with: <strong>OpsiMate</strong> (<a href="https://github.com/OpsiMate/OpsiMate"><strong>https://github.com/OpsiMate/OpsiMate</strong></a> ), which I worked on during release 0.2.</li>
<li>While reviewing feature requests, I found an issue that has not been implemented yet: <a href="https://github.com/OpsiMate/OpsiMate/issues/94"><strong>https://github.com/OpsiMate/OpsiMate/issues/94</strong></a> . It’s new, has reference implementations, and involves a reasonable amount of work. It felt like the right fit, so I decided to focus my efforts on contributing to OpsiMate.</li>
</ol>
]]></content:encoded></item><item><title>OSD600 Lab 8</title><link>https://www.parkerchenca.com/osd600/lab-8/</link><pubDate>Thu, 10 Sep 2026 11:43:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-8/</guid><description>CI, linters, and testing</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Another helpful hand, and more</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<p>This week I worked on GtHub Actions CI for my Go project, added a Go linter, and wrote tests for a partner’s repository. The lab overlapped with my Cloud Computing (CCP) course, so the CI work fit well with what I’m learning there.</p>
<p>Reflections</p>
<ul>
<li>I’m also taking CCP, so CI-related tasks felt practical.</li>
<li>I had already added CI in a previous lab (I thought “why not?” while I was adding tests), so I extended that work here.</li>
<li>Adding a Go linter was new to me (I know the eslint), but following the <code>golangci-lint</code> repo made it straightforward.</li>
</ul>
<h3 id="answering-questions">Answering questions</h3>
<h4 id="how-did-you-set-up-your-github-actions-ci-workflow-what-did-the-yaml-for-this-workflow-look-like">How did you set up your GitHub Actions CI Workflow? What did the YAML for this workflow look like?</h4>
<p>I searched “How can I set up my GitHub Actions CI Workflow?”, as just same as the question title. Then, I found a Go workflow templates by clicking the action button in GitHub. The workflow builds and tests on push and pull requests to <strong><code>main</code></strong> and <strong><code>dev</code></strong>. Super straightforward again.</p>
<p>Template YAML:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Go</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">push</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&#34;main&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;dev&#34;</span><span class="w"> </span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pull_request</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="s2">&#34;main&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;dev&#34;</span><span class="w"> </span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Set up Go</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/setup-go@v4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">go-version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;1.25.1&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">go build -v ./...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Test</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">go test -v ./...</span><span class="w">
</span></span></span></code></pre></div><h4 id="how-did-your-partners-repo-and-testing-setup-differ-from-yours-what-was-it-like-writing-tests-for-a-project-you-didnt-create">How did your partner&rsquo;s repo and testing setup differ from yours? What was it like writing tests for a project you didn&rsquo;t create?</h4>
<hr>
<p>My partner’s repo did not initially have CI now(I will check again later). They did provide example tests, which helped me a lot. Writing tests for someone else feels just like writing a feature, but you must understand more about the intended behavior before you can test it well.</p>
<h4 id="what-do-you-think-of-ci-now-that-youve-set-it-up-for-yourself">What do you think of CI now that you&rsquo;ve set it up for yourself?</h4>
<ul>
<li>CI acts as an automatic safety layer — it finds flaws before the changes are really applied to the main (or other danger zone).</li>
<li>It saves manual steps: every push triggers the same checks.</li>
<li>CI is also flexible: you can configure testing closer to the real deployment environment, which local runs can’t always match.</li>
</ul>
<h4 id="if-you-did-the-optional-challenges-talk-about-how-that-went-and-what-you-learned">If you did the optional challenges, talk about how that went and what you learned.</h4>
<p>I added <strong><code>golangci-lint</code></strong> via GitHub Action (the repo/documentation has a ready template). Check their repo and instruction: <a href="https://github.com/golangci/golangci-lint-action">https://github.com/golangci/golangci-lint-action</a></p>
<p>I was surprised when I found they actually have provided “ready-to-use” config lines that allow me to copy and paste and then run everything correctly.</p>
<p>Lesson: read official docs and search the marketplace before creating the wheel — many reusable actions already exist.</p>
]]></content:encoded></item><item><title>OSD600 Lab 7</title><link>https://www.parkerchenca.com/osd600/lab-7/</link><pubDate>Thu, 10 Sep 2026 11:42:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-7/</guid><description>Testing and testing the tests and test the testing</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude</strong>:
Code everywhere, tests everywhere, tokens everywhere, budget nowhere</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<h3 id="testing-commit">Testing commit:</h3>
<p><a href="https://github.com/BHChen24/repo2context/pull/36/commits">https://github.com/BHChen24/repo2context/pull/36/commits</a></p>
<h3 id="answering-lab-questions">Answering Lab Questions</h3>
<hr>
<ul>
<li>Which testing framework/tools did you choose? Why did you choose them? Provide links to each tool and briefly introduce them.
<ul>
<li>Since I my project is written by Go, so I just use the go test for testing: <a href="https://pkg.go.dev/testing">https://pkg.go.dev/testing</a></li>
<li>As described on the official page, it “provides support for automated testing of Go packages.” It’s also a part of the standard library, so it can be used directly when the Go environment is set.</li>
<li>At the beginning, I put the test files in another folder just like what I used to do with Typescript testing, but then I found it’s better to just place them beside the source code as a standard way in Go projects.</li>
<li>Use <code>go test [target folder/file]</code> to run tests, and use <code>go test -cover [target]</code> to see the test coverage</li>
</ul>
</li>
<li>How did you set them up in your project? Be detailed so that other developers could read your blog and get some idea how to do the same.
<ul>
<li>See above~ :)</li>
</ul>
</li>
<li>What did you learn while writing your test cases? Did you have any &ldquo;aha!&rdquo; moments or get stuck?
<ul>
<li>I felt writing tests is painful.</li>
<li>I have to consider each possible way to trigger an error, which is literally difficult to cover all the cases - also means I have to fully understand the tested target (mostly functions in Go).</li>
<li>Always, when I hand my tests to AI for reviewing, it will give more comprehensive test cases, like missing values, edge cases, input format, etc. I did learned a lot.</li>
<li>But I also begin to doubt that I can really memorize all useful cases. There are at least 10 to 15 cases for each function, even though there are some common cases I can reuse.</li>
<li>Maybe a test cases document is the truly practical tool for the testing.</li>
<li>I also made good use of “given-when-then” pattern for writing the tests. (See <a href="https://github.com/BHChen24/repo2context/blob/main/pkg/scanner/scanner_test.go">https://github.com/BHChen24/repo2context/blob/main/pkg/scanner/scanner_test.go</a>) It’s super helpful for planning the test process.</li>
</ul>
</li>
<li>Did your tests uncover any interesting bugs or edge cases?
<ul>
<li>No for this time. But I am curious about why I didn&rsquo;t find any bugs… Maybe more tests will reveal some, or I need more time to review my tests.</li>
</ul>
</li>
<li>What did you learn from this process? Had you ever done testing before? Do you think you&rsquo;ll do testing on projects in the future?
<ul>
<li>Actually I have done the tests in the Lab6 (See <a href="https://github.com/BHChen24/repo2context/blob/main/pkg/tokenCounter/tokenCounter_test.go">https://github.com/BHChen24/repo2context/blob/main/pkg/tokenCounter/tokenCounter_test.go</a>)</li>
<li>At that time, I just simply thought that, “oh, since I will develop a new feature, maybe developing the tests at the same time is a good idea,” and then I created the tests beside it.</li>
<li>I think doing the testing is a standard step for developing reliable applications, so I definitely will do that in my future projects.</li>
<li>But I am actually feeling weird… Since each test case can be different, I’d like to say I’ve learned a lot from past tests, but for the next test I may still go blank with the new situation… Even though I know how to apply the test pattern, most of the time I still need to find some references to implement the test logic. Is it normal or not?</li>
</ul>
</li>
</ul>
<h3 id="experience-with-speckit">Experience with Speckit</h3>
<hr>
<p>As the additional content, I’d like to mention the new AI related tool called <a href="https://github.com/github/spec-kit">**Speckit</a>, built by GitHub.**</p>
<p><img alt="Speckit installing screen" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.20.28.png"></p>
<p>Speckit installing screen</p>
<p>This week, I tried it on my project and generated some scope-focused documentation for adjusting the AI assistant’s behavior towards my project.</p>
<p>Tldr, it looks good, but it didn’t reach my expectation for budget and left some confusion about how it understands the project context.</p>
<p>Firstly, as a CLI tool, it can generate corresponding commands for popular AI assistant tools such as Claude Code, Codex CLI (I use cursor-agent cli), <strong>and then</strong>, helps you to generate the project documentation. Which means you still have to call the api for creating the docs, and it has a lot of strict rules:</p>
<p><img alt="To-do list for generating plans" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.18.52.png"></p>
<p>To-do list for generating plans</p>
<p>As you may see, besides the plan, we also have <strong>constitution</strong> and <strong>specify</strong> that need to be created before, and then we have <strong>tasks</strong> to generate, finally <strong>implement</strong> it.</p>
<p>The full chain is <strong>constitution</strong> → <strong>specify</strong> → <strong>plan</strong> → <strong>tasks</strong> → <strong>implement;</strong> they all could be generated or run in the chat box with the AI assistant by slash commands like <code>/speckit.* [your chat content]</code>.</p>
<p>The quality of documentation is fantastic, as you have all the practical built-in rules in the speckit:</p>
<p><img alt="A lot of .md files" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.19.00.png"></p>
<p>A lot of .md files</p>
<p>Good project understanding and constitution set up:</p>
<p><img alt="Nearly wonderful and comprehensive documentation" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-06_at_16.08.26.png"></p>
<p>Nearly wonderful and comprehensive documentation</p>
<p>And quality checking:</p>
<p><img alt="Screenshot 2025-11-05 at 18.18.40.png" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.18.40.png"></p>
<p>But, the token consumption is also beautiful:</p>
<p><img alt="3 million token cost in minutes" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.23.51.png"></p>
<p>3 million token cost in minutes</p>
<p>At that point it exactly hit me like: for some project this small, <strong>Speckit</strong> steering the ship was overkill.</p>
<p>In addition, it did help me to create a new branch for implementing new test:</p>
<p><img alt="Helpful hand" loading="lazy" src="/osd600/lab-7/Screenshot_2025-11-05_at_18.18.19.png"></p>
<p>Helpful hand</p>
<p>However, it ignored my git context and named “001-test-xxx” (implicitly pointing to issue 1) the new branch, while I am currently at the “33-add-more-tests” branch. I think it’s just, not perfect, though I still paid a lot of token.</p>
<p>In the end, I found the <strong>Speckit</strong> is a really practical tool - there’s so much documentation for the AI to follow, that its behavior stays nicely in check (though I still think any AI-generated docs need a human adjust). However, for a small personal project like mine, I haven’t felt a huge payoff yet.</p>
<p>If you are interested, you can also have a try on it in your projects. :&gt;</p>
]]></content:encoded></item><item><title>OSD600 Release 0.2 recap</title><link>https://www.parkerchenca.com/osd600/release-0-2-recap/</link><pubDate>Thu, 10 Sep 2026 11:41:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-2-recap/</guid><description>Everything you did in October</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Journey of open-source contribution</p>
</blockquote>
<h2 id="in-october-in-hacktoberfest">In October, in Hacktoberfest…</h2>
<h3 id="what-i-did"><strong>What I did</strong></h3>
<hr>
<p>At first, I helped my friend build <strong>his open-source project</strong>. I introduced him to Hacktoberfest and added issue and PR templates to his project to make it easier for more people to contribute. Project link: <a href="https://github.com/TemaDeveloper/library_proj"><strong>https://github.com/TemaDeveloper/library_proj</strong></a></p>
<p>Then, I found a fun “<strong>cat card battle</strong>” project on GitHub. I joined it just because it looked interesting - and I love cat pictures. I also noticed that it is a new project created for Hacktoberfest, not too hard, but still meaningful (Not just “add yourself to the Contributors.md”). I contributed code to help the project fetch cat images correctly. Project link: <a href="https://github.com/JessieVela/cat-card-battle"><strong>https://github.com/JessieVela/cat-card-battle</strong></a></p>
<p>My next two PRs were for the <strong>OpsiMate</strong> project. This project has about 200 stars with a very active open-source community. They even use Slack to make announcements regularly. The reason why I choose this project is after working on two smaller projects, I wanted to join a bigger one that needed more communication and coordination - and OpsiMate was a good match. I unified their <code>eslint</code> and <code>prettier</code> config files, and also helped write some tests. Project link: <a href="https://github.com/OpsiMate/OpsiMate"><strong>https://github.com/OpsiMate/OpsiMate</strong></a></p>
<h3 id="how-ive-progressed">how I&rsquo;ve progressed</h3>
<hr>
<p>The beginning was difficult. Honestly, the assignment really pushed me to start - because I needed to complete something for the marks. But once I made the first try, I realized most problems were not as hard as I thought.</p>
<p>The hardest part for me was <strong>finding the right issues</strong>. The hacktoberfest tag and my classmates’ sharing on Teams helped a lot. I also learned a lot about GitHub search. Here&rsquo;s a document I often used and recommend to others:</p>
<p><a href="https://docs.github.com/en/search-github/github-code-search/understanding-github-code-search-syntax"><strong>https://docs.github.com/en/search-github/github-code-search/understanding-github-code-search-syntax</strong></a></p>
<p>Then came <strong>reading and understanding code</strong> - or more exactly, understanding the whole structure of a repository. Usually, a repo has many tools like ESLint, pnpm, biome, etc. These tools may not be part of the main logic, but if they are not configured correctly, the project cannot even run, and there is no way to develop and test the project. I once tried a project that I couldn’t make run locally, and I finally had to give up: <a href="https://github.com/BHChen24/flexprice">**https://github.com/BHChen24/flexprice</a>** (If you are interested, you can give it a try.)</p>
<p>Another important part is using <strong>soft skills</strong>, like time management and communication. Good <strong>time management</strong> is important. our professor has told us many times not to push all PRs at the last minute. I tried to make a detailed schedule with flexible options. For example, one week I was sick and couldn’t finish my PR by Friday, but I finished it during the weekend. That was the “acceptable case” in my plan. I also had other priority levels and fallback plans, such as contacting the professor if needed. In longer projects, unexpected things can always happen, so it’s important to track progress and prepare alternatives.</p>
<p>About <strong>communication</strong> - I noticed many open-source contributors communicate in a very casual way. Maybe that’s a community habit. But some comments like “Hey, give me the issue” feel a bit rude to me. I saw that some people spoke like that and then received no reply 😂. So  I try to be polite and neutral, and keep my messages short. Being too formal can also confuse others, I think.</p>
<p>I also learned that timely <strong>follow-up</strong> is important, because not everyone is a full-time open-source developer. For example, when I was debugging in the cat card project, the author only replied after I mentioned them - so if I had stayed silent, nothing would have moved forward.</p>
<h3 id="what-i-learned">What I learned</h3>
<hr>
<p>I think my biggest improvement is getting to know <strong>how to read code</strong> in a better way. Now, when I start working on a project, I know exactly what to check first: read the <strong><code>README.md</code></strong>, look at the repository’s insights ****tab, read the <strong><code>CONTRIBUTE.md</code></strong> file, etc. I also learned how to use good tools when reading code — I always search first, and then use “go to definition/references” to jump precisely to related code. I scroll much less with my mouse now.</p>
<p>I also became more confident using <strong>Git</strong>. I use Git often in assignments and at my internship, and I’ve learned some useful details. For example, if I publish a branch first and then rebase, the history becomes very messy like spaghetti - and everyone can see it. But if I don’t publish before rebasing, the worst thing is just a local conflict, which I can solve privately. Then when I publish, the history looks clean and is easier for reviewers to follow.</p>
<p>I also gained inspiration on how to build reliable projects by reading <strong>clean repositories</strong>, like this one: <a href="https://github.com/yamadashy/repomix/"><strong>https://github.com/yamadashy/repomix/</strong></a></p>
<p>Another repo I liked is <a href="https://github.com/juspay/hyperswitch"><strong>https://github.com/juspay/hyperswitch</strong></a> . I didn’t have a chance to contribute yet, but it’s a great example of how to build a financial project in Rust, a direction I’m very interested in. I’ll keep following it.</p>
<h3 id="considerations"><strong>Considerations</strong></h3>
<hr>
<p>I think I made some progress during Hacktoberfest, but this is still just the beginning.</p>
<p>I had planned to contribute to larger projects (with maybe over 2k stars), but due to time, strange build errors, and some unexpected competition, I chose a safer way to meet the requirements of the course first. Still, I really want to contribute to big projects. Some of my classmates have already done that, and after this round of Hacktoberfest, I finally feel confident enough to try it too in the future.</p>
<p>By the way… seeing my avatar appear in the Contributors list makes me feel kind of proud.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.2 Week 4</title><link>https://www.parkerchenca.com/osd600/release-0-2-week-4/</link><pubDate>Thu, 10 Sep 2026 11:40:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-2-week-4/</guid><description>Last PR for the release 0.2</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
We ****need to be tested for sure</p>
</blockquote>
<h2 id="in-release-02-week-4">In release 0.2 week 4…</h2>
<hr>
<h3 id="what-i-did"><strong>What I did</strong></h3>
<p>This week I contributed in another issue in the project <a href="https://github.com/OpsiMate/OpsiMate"><strong>OpsiMate</strong></a>, - the same one I contributed to last week.</p>
<p>My main task was to add test cases for one of the APIs.</p>
<hr>
<h3 id="working-on-issuepr"><strong>Working on (issue/PR)</strong></h3>
<p>Here’s the issue I picked up: <a href="https://github.com/OpsiMate/OpsiMate/issues/371">https://github.com/OpsiMate/OpsiMate/issues/371</a></p>
<p>And here’s my pull request:  <a href="https://github.com/OpsiMate/OpsiMate/pull/537">https://github.com/OpsiMate/OpsiMate/pull/537</a></p>
<p>This issue was a bit of a “legacy” one. Someone had tried working on it before, but their PR was rejected. Another contributor also took it but later unassigned themselves.</p>
<p>When I saw it sitting there for a while, I thought “Why not give it a try?” So I volunteered to take it on. Right now, both the issue and my PR are still waiting for review.</p>
<hr>
<h3 id="need-to-know"><strong>Need to know</strong></h3>
<p>The issue focused on writing tests using the <code>Supertest</code> framework, which is quite similar to <code>Vitest</code>. By looking at existing tests in the project, I quickly figured out how to use it.</p>
<p>It was also very helpful to check some closed issues and PRs - there are lots of good examples there.</p>
<hr>
<h3 id="difficulties--fixes"><strong>Difficulties &amp; Fixes</strong></h3>
<p>While testing, I actually found a few bugs in the original API code.</p>
<p>It seems the API didn’t have proper <code>try-catch</code> logic, so it couldn’t return the correct response status. Because of that, I had to mention this problem in my PR - basically saying, “Hey, this API might have a bug. It should be fixed before we can finalize the tests.”</p>
<p>I submitted a draft PR temporarily. The maintainers might ask me to fix the bug as well, or maybe just provide more guidance on the tests. Either way, I just need to wait for the review.</p>
<hr>
<h3 id="considerations"><strong>Considerations</strong></h3>
<p>I’ve seen some test code that doesn’t really “test” anything - it just exists to make the tests pass.</p>
<p>With AI tools becoming more common in development, this problem might get even more serious: AI can help you generate tests quickly, but those tests might only aim to pass instead of really verifying quality (especially when you tell the AI, “Hey, this code doesn’t work!”).</p>
<p>In my experience, my tests did help me discover real issues and hidden bugs, which shows how valuable testing can be - even if it’s sometimes tedious.</p>
<p>Combining AI-assisted coding with good testing practices is definitely an interesting topic worth exploring in the future.</p>
]]></content:encoded></item><item><title>OSD600 Lab 6 Developing</title><link>https://www.parkerchenca.com/osd600/lab-6-developing/</link><pubDate>Thu, 10 Sep 2026 11:39:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-6-developing/</guid><description>Implement new feature for my project</description><content:encoded><![CDATA[<h2 id="main-content">Main Content</h2>
<h3 id="the-feature">The feature</h3>
<p>I implemented the token counting feature inspired by the <strong>Repomix</strong> project in this lab.</p>
<p>The feature displays the token cost calculated by a specific model align with each file in the file tree. Users can better manage API call budget now. For example:</p>
<p><img alt="Screenshot 2025-10-27 at 16.34.20.png" loading="lazy" src="/osd600/lab-6-developing/Screenshot_2025-10-27_at_16.34.20.png"></p>
<p>I also added corresponding tests to ensure reliability.</p>
<h3 id="the-development">The development</h3>
<p>In the development step, I tried to apply the TDD pattern</p>
<p>To follow it, I wrote the tests first with AI assistance. Tests provided a clear direction for developing, though some tests turned out to be tricky or hard to satisfy (because they are generated by AI… A strict tech leader!)</p>
<p>In the end, I still have to ask AI for help or frequently search my question online… But I think this experience is valuable.</p>
<h3 id="the-inspiration">The inspiration</h3>
<ul>
<li>Directly referring the pattern for applying tiktoken library in Repomix:
<ul>
<li><code>this.encoding = get_encoding(encodingName);</code> → <code>tke, err := tiktoken.GetEncoding(encoding)</code></li>
</ul>
</li>
<li>Writing test to make the feature more robust (just like what Repomix has done)</li>
<li>The difference, which is also the challenge, is passing text into the new function and handling the output. Due to the project structure, this is totally different from Repomix so I have to review my code again and try to find a best way to integrate the function into my project
<ul>
<li>Then I noticed that I need to do more refactoring work later.</li>
</ul>
</li>
</ul>
<h3 id="next-step">Next step</h3>
<p>I want to add more tests for all features in the project. Also, there are more and more lines piling up in the <code>core.go</code> so I may have to refactor most of the code in it (blame the past me) by wrapping more logic into functions.</p>
<h3 id="other-interesting-things">Other Interesting things..</h3>
<p>CodeRabbitAI gave a wrong suggestion for code changing that broke my CI/CD pipeline! (Do not trust AI so hard&hellip;)</p>
]]></content:encoded></item><item><title>OSD600 Lab 6 Reading</title><link>https://www.parkerchenca.com/osd600/lab-6-reading/</link><pubDate>Thu, 10 Sep 2026 11:38:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-6-reading/</guid><description>Read the code, understand the project</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
If I cannot understand the project, how can I write my own code?</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<h3 id="introduction-of-the-target-feature">Introduction of the target feature</h3>
<p>The feature I focused on is <strong>token counting</strong>. This component is responsible for calculating how many tokens a given text input contains.</p>
<p>I ran the <a href="https://github.com/yamadashy/repomix">**repomix</a>** project locally and got output like below:</p>
<p><img alt="Screenshot 2025-10-27 at 10.57.03.png" loading="lazy" src="/osd600/lab-6-reading/Screenshot_2025-10-27_at_10.57.03.png"></p>
<p>Which I think it’s exactly the feature I need for controlling the cost of calling LLM APIs.</p>
<h3 id="explore-the-codebase">Explore the codebase</h3>
<p>To understand the implementation, I went through the official documentation and source code of the project.</p>
<ul>
<li><strong>Read <a href="https://repomix.com/">the official website</a></strong> – This provided a general overview of what the project does and how it can be used.</li>
<li><strong>Read <a href="https://github.com/yamadashy/repomix">the GitHub main page</a></strong> –The project is written in <strong>TypeScript</strong>, and the main repository offers clear descriptions of the project’s capabilities and setup process.</li>
<li><strong>Read <code>README.md</code></strong> – This basically is the main content of the GitHub page.</li>
<li><strong>Read <code>package.json</code></strong> – From here, I learned about the project’s dependencies, scripts, and build process.</li>
<li><strong>Read <code>CONTRIBUTING.md</code></strong> – This document describes how to develop and contribute to the project. While reading, I also noticed that there is an additional instruction file called <strong><code>repomix-instruction.md</code></strong>, which gives more detailed guidelines.</li>
<li><strong>Build and run locally</strong> – After understanding the setup, I built and executed the project on my local machine to test it directly.</li>
<li><strong>Locate feature implementations</strong> – I identified the files where the token counting logic is implemented by:
<ul>
<li><strong>Ask <code>Claude Code</code></strong> – The project provides a <strong><code>CLAUDE.md</code></strong> file with instructions for AI-assisted development.</li>
</ul>
</li>
<li><strong>Most important file</strong> – The core logic resides in <a href="https://github.com/yamadashy/repomix/blob/main/src/core/metrics/TokenCounter.ts"><strong><code>src/core/metrics/TokenCounter.ts</code></strong></a>. Other related implementations can be found by tracing symbol references from this file.</li>
<li><strong>Read both the main source code and test files</strong> – Doing this helped me understand the internal structure and how the feature is being used in different contexts:</li>
</ul>
<p><img alt="Screenshot 2025-10-27 at 11.09.52.png" loading="lazy" src="/osd600/lab-6-reading/Screenshot_2025-10-27_at_11.09.52.png"></p>
<h3 id="the-way-to-understand-the-project">The way to understand the project</h3>
<p>One challenge was understanding the <strong>tiktoken</strong> library.</p>
<p>Originally, <strong><code>tiktoken</code></strong> is a Python package, but this project uses its TypeScript implementation. Since my project uses Go, I had to search for a Go version online. I found <a href="https://github.com/pkoukk/tiktoken-go"><strong><code>pkoukk/tiktoken-go</code></strong></a>, but after reviewing its issues I discovered that a newer maintained fork exists: <a href="https://github.com/localit-io/tiktoken-go"><strong><code>localit-io/tiktoken-go</code></strong></a>. I decided to use the newer one.</p>
<p>While exploring the implementation, I also found some hardcoded parameters in Repomix, which indicate the project’s default behavior (as shown in my screenshots):</p>
<p><img alt="Screenshot 2025-10-27 at 11.45.04.png" loading="lazy" src="/osd600/lab-6-reading/Screenshot_2025-10-27_at_11.45.04.png"></p>
<p>It wasn’t very difficult to understand the class pattern in TypeScript, since we have already learned similar concepts in our C++ and Java courses.</p>
<p>I also noticed there are many utility (“util”) functions used throughout the code:</p>
<p><img alt="Screenshot 2025-10-27 at 11.48.46.png" loading="lazy" src="/osd600/lab-6-reading/Screenshot_2025-10-27_at_11.48.46.png"></p>
<p>As you can see, except for the line <code>this.encoding = ...</code>, most of the other lines are mainly responsible for:</p>
<ul>
<li>setting timers for performance testing</li>
<li>logging the operations</li>
</ul>
<p>These parts are not the core logic of token counting; they mainly support it by monitoring and recording runtime behavior.</p>
<p>And, it also has a lot of error handling code:</p>
<p><img alt="Screenshot 2025-10-27 at 11.48.55.png" loading="lazy" src="/osd600/lab-6-reading/Screenshot_2025-10-27_at_11.48.55.png"></p>
<p>Being able to identify their purposes can reduce the mental load when reading the code.</p>
<h3 id="learned">Learned</h3>
<p>The key to understanding a large codebase is to focus on the core business logic first. Identify which parts handle essential functionality, and which are for error handling, performance monitoring, or utility purposes. While those are important, they are not the main focus for my target feature.</p>
<p>In addition, navigating through references is also very helpful for understanding the codebase. I spent some time learning how to use the “Go to Definition / Type Definition / Implementation / References” features in my editor, and once I got used to them, they saved a lot of time by precisely revealing the details I needed to know.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.2 Week 3</title><link>https://www.parkerchenca.com/osd600/release-0-2-week-3/</link><pubDate>Thu, 10 Sep 2026 11:37:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-2-week-3/</guid><description>The third PR. Be a part of the project.</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I am one part of a group of a hundred developers?!</p>
</blockquote>
<h2 id="in-release-02-week-3">In release 0.2 week 3…</h2>
<hr>
<h3 id="what-i-did"><strong>What I did</strong></h3>
<p>This week I participated in the project that was recommended by my classmates: <a href="https://github.com/OpsiMate/OpsiMate"><strong>OpsiMate</strong></a>; it&rsquo;s truly an active open-source project—once I commented on an issue, there was a contributor to reply to me in time.</p>
<p>I also joined their slack channel and found they even have short but regular reports for community growth, which makes me really feel like I am a part of the project.</p>
<hr>
<h3 id="working-on-issuepr"><strong>Working on (issue/PR)</strong></h3>
<p>The issue I worked on is: <a href="https://github.com/OpsiMate/OpsiMate/issues/517">https://github.com/OpsiMate/OpsiMate/issues/517</a> and this is the related PR for it: <a href="https://github.com/OpsiMate/OpsiMate/pull/521">https://github.com/OpsiMate/OpsiMate/pull/521</a></p>
<p>This issue is about adjusting the project’s linting and formatting configurations. Before, there were several config files in different folders, such as the app server folder, the client folder, and the shared package folder. So one of the main contributors wants to create unified base configs for both the linter and the formatter in order to manage them in a standardized way.</p>
<hr>
<h3 id="need-to-know"><strong>Need to know</strong></h3>
<p>After analyzing the codebase, I realized that the project is mainly using <code>eslint.config.js/mjs</code> and <code>.prettierrc</code> as the configuration files. S
the first thing I need to figure out is how prettier and eslint reads their configs from specific files.</p>
<p>And, obviously, <code>.prettierrc</code> doesn’t support importing or exporting, so I need to find a way to transit config objects within config files.</p>
<hr>
<h3 id="difficulties"><strong>Difficulties</strong></h3>
<p>It’s not so hard to find the online resources and apply them to create a new base config file that is accepted by prettier. But the eslint configs seem to be more complex.</p>
<p>Furthermore, once the eslint configuration is broken, it will spread out to subdomains and eventually lead to a failed CI/CD workflow (I made one mistake and then there were a huge number of red error messages that freaked me out). So I need to take it more carefully and frequently ask for help.</p>
<hr>
<h3 id="fixes"><strong>Fixes</strong></h3>
<p>To be honest, the fixings are not so special or awesome; I basically just followed online instructions plus a little bit of my personal experience to accomplish this issue. If I made a mistake, the local IDE tools like SonarQube, eslint and prettier plugin would correct me before making changes; besides, this project applied the CodeRabbitAI for GitHub PR reviewing. I got a lot of useful suggestions for improving my bug-fixing code. Everything just looks like it&rsquo;s running smoothly and under control.</p>
<hr>
<h3 id="considerations"><strong>Considerations</strong></h3>
<p>There are a few interesting thoughts I want to mention here but, I don’t know if I should write some super long paragraphs for each of those 😂, so I decide to list them below as bullet points:</p>
<ul>
<li>Technically speaking, this is my first time participating in a project that has a public developing community; my first PR was made for my friend, and my second PR was made for a hacktoberfest-specific project (I think. But it still is a fun project!). So I am very exciting for this week’s work.</li>
<li>Eslint9 doesn&rsquo;t support <code>extend</code> syntax anymore, but my work was based on a previous version, so I did pay for it with some useless effort. Thankfully I noticed this problem from the code reviewer. Should take more care about the version of developing tools next time.</li>
<li>Slack seems super useful for communication. It also likes the discord… Maybe I should take some time to learn about it.</li>
<li>Do not feel afraid of following up on the work. Eventually we should push the process somehow.</li>
</ul>
]]></content:encoded></item><item><title>OSD600 Release 0.2 Week 2</title><link>https://www.parkerchenca.com/osd600/release-0-2-week-2/</link><pubDate>Thu, 10 Sep 2026 11:36:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-2-week-2/</guid><description>The second PR</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Shall we have a talk about the strange issues?</p>
</blockquote>
<h2 id="in-release-02-week-2">In release 0.2 week 2…</h2>
<hr>
<h3 id="what-i-did"><strong>What I did</strong></h3>
<p>This week I mainly worked on a small but interesting project: Cat Card battle (<a href="https://github.com/JessieVela/cat-card-battle">https://github.com/JessieVela/cat-card-battle</a>). It’s a web-based game built with <strong>Vue</strong> and <strong>TypeScript</strong>, and styled using <strong>Tailwind CSS</strong>.</p>
<hr>
<h3 id="working-on-issuepr"><strong>Working on (issue/PR)</strong></h3>
<p>Early this week, I found a bug that caused some image URLs from <strong>The Cat API</strong> to redirect to Tumblr’s “content violation” placeholder instead of showing actual cat photos. Like this:</p>
<p><img alt="Screenshot 2025-10-17 at 10.42.19.png" loading="lazy" src="/osd600/release-0-2-week-2/Screenshot_2025-10-17_at_10.42.19.png"></p>
<p>(Also see: <a href="https://github.com/JessieVela/cat-card-battle/issues/23">https://github.com/JessieVela/cat-card-battle/issues/23</a>)</p>
<p>So I decided to file this bug as an issue, and see if I can be assigned then fix it.</p>
<hr>
<h3 id="need-to-know"><strong>Need to know</strong></h3>
<p>I have some experience with the <strong>Vue</strong> framework, but I needed to review a few of its concepts. Fortunately, the bug didn’t require any functional changes, so I could focus purely on <strong>TypeScript</strong> logic.</p>
<p>The next thing I needed was to understand how to use <strong>The Cat API</strong>. Luckily, they provide detailed documentation:</p>
<p><a href="https://developers.thecatapi.com/view-account/ylX4blBYT9FaoVd6OhvR?report=bOoHBz-8t">https://developers.thecatapi.com/view-account/ylX4blBYT9FaoVd6OhvR?report=bOoHBz-8t</a></p>
<hr>
<h3 id="difficulties"><strong>Difficulties</strong></h3>
<p>The main challenge this week was Tumblr’s redirection behavior.</p>
<p>I used the <strong>Network</strong> tab in DevTools to trace why placeholder images were being returned and where they came from. Eventually, I found that some image requests returned a <strong>301</strong> status code, with a <strong>Location</strong> header pointing to a placeholder image.</p>
<p>To handle this, I added logic to detect 301 responses and fetch the image again. But strangely, even after refetching, the placeholder problem was still there. This make me wonder that whether I should dig deeper into Tumblr’s API mechanism — though that might have been too complex.</p>
<p>I finally decided that the issue was likely on <strong>The Cat API’s</strong> side, and it wasn’t worth pursuing further.</p>
<hr>
<h3 id="fixes"><strong>Fixes</strong></h3>
<p>For the Tumblr image issue, I implemented a simple workaround: <strong>temporarily filter out Tumblr-sourced images.</strong> If an image source is detected to be from Tumblr, the app simply re-fetches until it gets the required number of images.</p>
<p>Now, all images come from CDN sources, which should theoretically be more stable.</p>
<p>Another challenge was <strong>communication</strong>.</p>
<p>After submitting the issue, the repository owner didn’t respond, but they did close another issue during that time. I feel a little bit confused about that but also not sure if I should follow up with them.</p>
<p>Since I already submitted a PR, I decided to wait for a while and may reach out to them proactively if there’s still no reply.</p>
<hr>
<h3 id="considerations"><strong>Considerations</strong></h3>
<p>While handling the Tumblr image issue in the PR, I felt a lot of pain — every attempt to “check and re-fetch” still resulted in placeholder images. Then I realized something: if the goal is simply to <strong>solve</strong> the problem, a simpler solution works just as well — the source is unreliable, then I can just don’t use it.</p>
<p>Perhaps in practice, solving a problem doesn’t always require overthinking — sometimes the simplest solution is still effective.</p>
]]></content:encoded></item><item><title>OSD600 Lab 5</title><link>https://www.parkerchenca.com/osd600/lab-5/</link><pubDate>Thu, 10 Sep 2026 11:35:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-5/</guid><description>Rebase and amend</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Even more powerful commands for version control</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<p>Write a blog post about the process of refactoring your code.</p>
<ul>
<li>What did you focus on in your improvements? How did you fix your code so it would be better in each step?</li>
<li>How did your interactive rebase go? Did you find any bugs in your code while you did this? Did you break your program while changing things?</li>
<li>How did it go using Git to change your project&rsquo;s history?</li>
</ul>
<h3 id="what-did-you-focus-on-in-your-improvements">What did you focus on in your improvements?</h3>
<p>I mainly focused on looking for big code blocks to implement my improvements because it has a higher chance of discovering a function that can be exacted. At the same time, I was also looking for a chance to rename some vague variables and add comments to logic.</p>
<p>I used a code quality checking plugin called <strong>SonarQube</strong> (<a href="https://www.sonarsource.com/products/sonarlint/">https://www.sonarsource.com/products/sonarlint/</a>) to find potential issues in my code. Here is the showcase:</p>
<p><img alt="Screenshot 2025-10-06 at 17.50.13.png" loading="lazy" src="/osd600/lab-5/Screenshot_2025-10-06_at_17.50.13.png"></p>
<p>As you can see, SonarQube lists its concerns for my codebase. It’s convenient, but if you are also using Go for programming, you must have noticed that: <code>if err != nil</code> is basically inevitable, counting it into the complexity value is meaningless. It&rsquo;s still a good tool for pre-checking our code though.</p>
<h3 id="how-did-your-interactive-rebase-go">How did your interactive rebase go?</h3>
<p>Interactive rebase is surprisingly good, plus I found that <strong>GitLens</strong> (<a href="https://www.gitkraken.com/gitlens">https://www.gitkraken.com/gitlens</a>) provides a pretty UI with the IDE like VS Code.</p>
<p><img alt="Screenshot 2025-10-06 at 18.00.41.png" loading="lazy" src="/osd600/lab-5/Screenshot_2025-10-06_at_18.00.41.png"></p>
<p>(Reference: <a href="https://www.gitkraken.com/learn/git/problems/git-interactive-rebase">https://www.gitkraken.com/learn/git/problems/git-interactive-rebase</a>)</p>
<p>I don’t need to be too concerned about the looking of the submit tree now because I learned how to rearrange it by &ldquo;rebase.&rdquo; Separately creating small commits also makes the workflow clearer when we are developing. But since it will break the branch - specifically, drop some commit histories - we should always use it on our own, personal topic branch (and we’d better know what we are exactly doing).</p>
<p>Since I only made minor changes, I didn&rsquo;t confront big issues in this lab, but I do have a story to tell in the next section.</p>
<h3 id="how-did-it-go-using-git-to-change-your-projects-history">How did it go using Git to change your project&rsquo;s history?</h3>
<p>Here is the concise story of using Git in my lab 5:</p>
<ul>
<li>I created new branch</li>
<li>I made changes</li>
<li>Too smoothly! I finished all 3 targets without making a commit!</li>
<li>Had to pick the file that need to be committed, and saved others for later commits… Used <code>add</code></li>
<li>In the middle of the way, noticed that the names of the local branch and the remote were different! Had to change them… (Then I deleted the remote one first, I don’t know why I did that.)</li>
<li><code>Rebase</code> but failed! Since Git couldn’t find the remote branch…</li>
<li>…</li>
</ul>
<p>Well you see, even though I finally managed to rebase my branch, the most difficult part still wasn&rsquo;t applying some Git commands but driving Git well from the very beginning. However, I got to know at least one thing: Git has most of the methods to help you keep the code history safe and operable (again, if you know what you’re doing there).</p>
<p>I feel like I only touched 30%~40% of Git&rsquo;s usages. It’s definitely worth investing time to learn it well.</p>
]]></content:encoded></item><item><title>OSD600 Release 0.2 Week 1 (Updated)</title><link>https://www.parkerchenca.com/osd600/release-0-2-week-1-updated/</link><pubDate>Thu, 10 Sep 2026 11:34:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-2-week-1-updated/</guid><description>First step in Hacktoberfest</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
<em>Everything&rsquo;s hard in the beginning</em></p>
</blockquote>
<h2 id="in-release-02-week-1">In release 0.2 week 1…</h2>
<h3 id="what-i-did"><strong>What I did</strong></h3>
<p>This week I mainly focused on searching for suitable open source projects to contribute to. I haven’t started submitting any pull requests yet, but I did managed to create an issue (see link below) and am waiting for it to be assigned.</p>
<p><a href="https://github.com/TemaDeveloper/library_proj/issues/17">https://github.com/TemaDeveloper/library_proj/issues/17</a></p>
<h3 id="working-on-issuepr"><strong>Working on (issue/PR)</strong></h3>
<p>I opened an issue about setting up <strong>issue templates</strong> for a repository. Although I think it was a simple one, it still was my first time dealing with this topic, so I referred to the official GitHub documentation. I surprisingly learned that using a <strong><code>.yml</code></strong> file for the issue template allows better formatting and a cleaner layout for users filling in issue forms than the <code>.md</code> template.</p>
<p>The process has been updated; please have a check on the &ldquo;Updated&rdquo; section in this post</p>
<h3 id="need-to-know"><strong>Need to know</strong></h3>
<p>Still waiting for feedback or assignment on my issue. Once that’s done, I plan to contribute my first PR to this project or one of the other candidates I’ve found.</p>
<h3 id="difficulties"><strong>Difficulties</strong></h3>
<p>The main challenge this week was <strong>finding the right project</strong> to start with. Some repositories are attractive and popular but have too many contributors already. It’s so hard to find available “good first issues.” in those repos.</p>
<h3 id="fixes"><strong>Fixes</strong></h3>
<p>After rewatching a previously recorded lecture, I realized I had overlooked GitHub’s <strong>advanced search</strong> feature. By also researching on the GitHub official documentation, I improved my efficiency in locating suitable issues by using <code>no:assignee</code>, etc. I’ve already starred several projects for upcoming work.</p>
<h3 id="considerations"><strong>Considerations</strong></h3>
<p>Some classmates shared potential projects on our team channel, and I found that exchanging ideas and experiences is really helpful. I believe active communication and collaboration will be key to achieving our release goals.</p>
<h3 id="updated">Updated</h3>
<p>I have added templates to the repo and The PR has been merged.</p>
<p><a href="https://github.com/TemaDeveloper/library_proj/pull/18">https://github.com/TemaDeveloper/library_proj/pull/18</a></p>
<p>Here are some things I want to share:</p>
<ol>
<li>Even though this PR is simple, it is somehow a little bit tricky. Because the templates will not be applied until the PR has been merged into the main repo (Github needs to read them), I have to create a new test repository in my account to test the templates.</li>
<li>And, this testing procedure did cause a bug: I mistakenly placed the templates in <code>.github/workflow/ISSUE_TEMPLATES</code> instead of the correct path <code>.github/ISSUE_TEMPLATES</code> in the original repo. However, in my separated test repo, the path is correct so that it didn&rsquo;t reflect any issue.</li>
<li>So after noticing the PR has been merged and the bug appeared, I still need to communicate with the owner to let him know I will create a new PR to fix the minor bug (<a href="https://github.com/TemaDeveloper/library_proj/pull/19">https://github.com/TemaDeveloper/library_proj/pull/19</a>). This cost extra time.</li>
</ol>
<p>This little issue got me thinking about how to handle PRs whose results only show after merging&hellip; I’d like to explore this topic further.</p>
]]></content:encoded></item><item><title>OSD600 Lab 4</title><link>https://www.parkerchenca.com/osd600/lab-4/</link><pubDate>Thu, 10 Sep 2026 11:33:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-4/</guid><description>Git remotes and merges to collaborate</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
PR, code review and communication.</p>
</blockquote>
<h2 id="refelction">Refelction</h2>
<hr>
<h3 id="first-how-did-the-code-itself-go"><strong>First, how did the code itself go?</strong></h3>
<p>The Python project I worked with is clean and straightforward. It made me reconsider my tech stack: I may use Python as my primary prototyping language, and only turn to Go, Rust, or C++ when specific requirements demand it.</p>
<h3 id="did-you-run-into-any-problems"><strong>Did you run into any problems?</strong></h3>
<p>Implementing the logic was simple, but writing tests was more difficult. Too many cases could be included!</p>
<h3 id="how-did-you-tackle-the-work"><strong>How did you tackle the work?</strong></h3>
<p>I looked up examples online and used some tools to inspire different test cases.</p>
<hr>
<h3 id="second-how-did-it-go-using-git"><strong>Second, how did it go using git?</strong></h3>
<p>Since I’ve been using Git continuously in recent months, I didn’t face major technical issues. The only recurring problem was occasionally forgetting to create a new branch, etc.</p>
<h3 id="did-you-find-any-of-it-difficult-how-did-you-get-around-this"><strong>Did you find any of it difficult? How did you get around this?</strong></h3>
<p>There was a tricky issue: I directly worked on my forked main branch and mentioned the original issue in one of the commit, so, the issue pointed back to my commit on the main branch. It’s a little bit confused because for a new feature I should have a clearly named branch links to the issue.</p>
<p>Luckily, I could still use the correct branch for making the new PR, but the comments are still left in the issue… And I feel like it’s troublesome to change the recorded behavior on Github.</p>
<p>I haven’t found a perfect solution for human-caused fault yet, so I simply try to be more careful. Fortunately, Git and GitHub are well-designed, so there’s usually a way to recover mistakes.</p>
<hr>
<h3 id="what-would-you-do-differently-next-time-what-did-you-learn-from-the-experience"><strong>What would you do differently next time? What did you learn from the experience?</strong></h3>
<p>In this week’s lab, a couple of tests passed locally but failed on the maintainer’s machine, so weird. I later realized that the issue was due to a mismatch between my local and pushed code.</p>
<p>Through communication we resolved it, but next time I will double-check my final code version. I also learned that consistent CI/CD pipelines and active communication are essential for online code contributing.</p>
]]></content:encoded></item><item><title>OSD600 Lab 3</title><link>https://www.parkerchenca.com/osd600/lab-3/</link><pubDate>Thu, 10 Sep 2026 11:32:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-3/</guid><description>Manage multiple simultaneous changes and use git merges</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Made a lot of mistakes, yet the actual merging process is very smoothly.</p>
</blockquote>
<h2 id="main-content">Main Content</h2>
<p>Project repo: <a href="https://github.com/BHChen24/repo2context">https://github.com/BHChen24/repo2context</a></p>
<p>Your issues:</p>
<p><a href="https://github.com/BHChen24/repo2context/issues/19">https://github.com/BHChen24/repo2context/issues/19</a></p>
<p><a href="https://github.com/BHChen24/repo2context/issues/20">https://github.com/BHChen24/repo2context/issues/20</a></p>
<p>Your merge commits:</p>
<p><a href="https://github.com/BHChen24/repo2context/commit/c9ae3957f1fa1749659181ba6c0773c1a7c9d0b8">https://github.com/BHChen24/repo2context/commit/c9ae3957f1fa1749659181ba6c0773c1a7c9d0b8</a></p>
<p><a href="https://github.com/BHChen24/repo2context/commit/4817fc097517a3c6a7daa8bbd7bcd1d02f25e2a3">https://github.com/BHChen24/repo2context/commit/4817fc097517a3c6a7daa8bbd7bcd1d02f25e2a3</a></p>
<p><strong>Reflections</strong>:</p>
<p>Discuss what you did, the changes you made for your features, and the process of doing your merges. What problems did you have? What did you learn? What would you do differently next time?</p>
<h3 id="merging-branches"><strong>Merging branches</strong></h3>
<p>I basically just followed the lab instructions and completed the main assignment, but I need to develop two extra features in separate branches because:</p>
<p>My initial approach was straightforward: create a branch, finish the feature, then make a PR. Since I followed this workflow step-by-step for each feature, I did not encounter any merge conflicts at all.</p>
<p>Later I realized I misunderstood the instructions. I actually need to trigger the merge conflicts by developing features in parallel, and then merging branches back in a line. I managed to develop two more features and did the fast-forward merge and a three-way merge.</p>
<p>Besides, I also filed some issues to reduce the number of function parameters or refine the output format.</p>
<p>Paid more effort due to begin the work so fast.</p>
<h3 id="what-i-learned"><strong>What I learned</strong></h3>
<p>The biggest lesson in this lab was not about the merges themselves but the importance of carefully reading instructions before diving in.</p>
<p>On the positive side of the first two issues (totally no conflicts but not align with the requirement), I confirmed that my personal development process could be good-for-work: open an issue, create a branch, link the issue to the branch commit (using GitHub keywords like <code>fixes #num</code>), then develop step by step.</p>
<p>For solo development this procedure keeps conflicts to a minimum. I  will still follow these steps next time.</p>
<p>However, in a collaborative environment, I think the conflicts are inevitable. That makes it essential to understand Git commands deeply and to take advantage of the rich ecosystem of version control tools.</p>
<p>(I also think that so many tools exist is proof that developers have been tortured by merge conflicts for years…)</p>
<h3 id="coderabbitai-code-review"><strong>CodeRabbitAI code review</strong></h3>
<p>Surprisingly, I discovered an auto-review tool while I was looking through examples of “how to file a good issue” on open-source projects.</p>
<p>What impressed me most was that tools like <strong>CodeRabbitAI</strong> can automatically generate a pull request summary, provide next-step suggestions, and even create sequence diagrams based on the code changes in the PR：</p>
<p><img alt="image.png" loading="lazy" src="/osd600/lab-3/image.png"></p>
<p>The whole report can be auto-generated and triggered by the work-in-process PR!</p>
<p>Here is an example I explored: <a href="https://github.com/BHChen24/repo2context/pull/25">https://github.com/BHChen24/repo2context/pull/25</a></p>
]]></content:encoded></item><item><title>OSD600 Release 0.1</title><link>https://www.parkerchenca.com/osd600/release-0-1/</link><pubDate>Thu, 10 Sep 2026 11:31:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/release-0-1/</guid><description>Building a Repository Context Packager command-line tool</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
This is my first step into building an open‑source style CLI tool in Go.</p>
</blockquote>
<h2 id="release-01">Release 0.1</h2>
<h3 id="project-description">Project Description</h3>
<p>For this assignment, I built a “Repository Context Packager” tool named <strong>repo2context</strong>, which can scan a local git repository and generate a single, well-structured text file with repository information optimized for sending to LLMs such as ChatGPT and Gemini.</p>
<h3 id="technology-choice">Technology Choice</h3>
<ul>
<li><strong>Language</strong>: Go (Golang)</li>
<li><strong>Output format</strong>: Markdown</li>
<li><strong>Why Go?</strong>: Although many people are talking about Go’s advantages all the time, my main reason to do this was simply that I wanted to challenge myself.</li>
</ul>
<h3 id="implemented-features">Implemented Features</h3>
<h4 id="required-features">Required Features</h4>
<ul>
<li>Basic CLI interface with <code>--help</code> and <code>--version</code></li>
<li>Repository/file analysis</li>
<li>Path tree structure</li>
<li>Git commit/branch metadata</li>
<li>Summary statistics (file count, lines of code)</li>
<li>Standard streams (stdout for output, stderr for errors)</li>
<li>Error handling</li>
</ul>
<h4 id="optional-features-implemented">Optional Features Implemented</h4>
<ol>
<li><strong>Gitignore Integration</strong>
<ul>
<li>The tool automatically excludes files and directories listed in <code>.gitignore</code>.</li>
<li>Provide a <code>--no-gitignore</code> to disable <code>.gitignore</code> filtering</li>
</ul>
</li>
<li><strong>Output to File</strong> (<code>-o</code> / <code>--output</code>)
<ul>
<li>
<p>Users can save the formatted repository context into a file (markdown text).</p>
</li>
<li>
<p>Example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">toolname . --output context.md
</span></span><span class="line"><span class="cl"><span class="c1"># usually the toolname is &#34;r2c&#34; but can be built as other names</span>
</span></span></code></pre></div></li>
</ul>
</li>
</ol>
<h3 id="development-experience">Development Experience</h3>
<h4 id="process">Process</h4>
<ol>
<li>Set up GitHub repository</li>
<li>Implement CLI argument parsing in Go (with <code>cobra</code> package)</li>
<li>Add recursive directory/file reading; Implement project structure tree displaying; tests…</li>
<li>Extract Git info (<code>os/exec</code> to run git commands and parse metadata)</li>
<li>Get data together and format output</li>
<li>Implement the two optional features: .gitignore handling + output to file</li>
<li>Also invite classmates to file issues</li>
</ol>
<h4 id="challenges">Challenges</h4>
<ul>
<li><strong>Git env:</strong> Needed to handle different situations like Git may not be available or the repo may not be initialized. (To be honest, I found this type of check should be applied to basically everywhere, and that’s a bit painful handling errors in Go..)</li>
<li><strong>Starting from scratch:</strong> This was my first time writing a full CLI tool in Go, so I had to set up everything from zero — project structure, flags, Git integration, error handling, etc. (Have to do a lot of research)</li>
</ul>
<h4 id="learnings">Learnings</h4>
<ul>
<li>Learned how to build a demo project from 0 to 0.1 in Go.</li>
<li>Gained experience reading Git metadata and filtering files dynamically.</li>
<li>Deepened understanding of how to do file system traversal, file I/O and error handling in Go.</li>
</ul>
<h3 id="summary">Summary</h3>
<ul>
<li>Implemented <strong>all required features</strong></li>
<li>Completed <strong>2 optional features</strong></li>
<li>A not bad foundation for future extensions</li>
<li>Good start for practicing open-source contribution process</li>
</ul>
<h3 id="links">Links</h3>
<ul>
<li><strong>GitHub Repository</strong>: <a href="https://github.com/BHChen24/repo2context/">https://github.com/BHChen24/repo2context/</a></li>
</ul>
]]></content:encoded></item><item><title>OSD600 Lab 2</title><link>https://www.parkerchenca.com/osd600/lab-2/</link><pubDate>Thu, 10 Sep 2026 11:30:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-2/</guid><description>Contributing and submitting Pull Requests</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
About the process of contributing a code change to another project</p>
</blockquote>
<h2 id="-main-content">🖋️ Main Content</h2>
<p>The project repo: <a href="https://github.com/RiverDave/rust-cli-tool">https://github.com/RiverDave/rust-cli-tool</a></p>
<p>Your issue: <a href="https://github.com/RiverDave/rust-cli-tool/issues/27">https://github.com/RiverDave/rust-cli-tool/issues/27</a></p>
<p>Your pull request: <a href="https://github.com/RiverDave/rust-cli-tool/pull/28">https://github.com/RiverDave/rust-cli-tool/pull/28</a></p>
<h3 id="1-what-i-did">1. What I did</h3>
<p>Briefly speaking, I did:</p>
<ul>
<li>First take a look at the whole project to see the current situation</li>
<li>Check if the “recent file” feature has been implemented</li>
<li>Analyze code base to see how to add custom commands</li>
<li>Search online for obtaining file metadata in certain language</li>
<li>Raise issue, fork repo, switch branch, develop logics</li>
<li>Test my code</li>
<li>Update documentation</li>
<li>Create PR</li>
<li>Communicate with repo owner</li>
<li>Close issue</li>
<li>Write blog</li>
</ul>
<h4 id="11-the-changes-i-made-for-my-feature">1.1 The changes I made for my feature</h4>
<ul>
<li>
<p>I found the rust project used <code>clap</code> — a famous and solid <strong>Command Line Argument Parser for Rust</strong>.</p>
</li>
<li>
<p>Thanks for that, I have a very clear pattern to follow then create a new command for the application:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#[arg(long = </span><span class="s">&#34;recent&#34;</span><span class="cp">)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">pub</span><span class="w"> </span><span class="n">recent</span>: <span class="kt">bool</span><span class="p">,</span><span class="w">
</span></span></span></code></pre></div><p>As simple as it looks like!</p>
</li>
<li>
<p>Then, I extended the <code>Config</code> struct to include a <code>recent_only</code> field, which controls whether to filter for recent files.</p>
</li>
<li>
<p>Next, I create useful logics in the <code>file.rs</code>. The main filtering logic checks if files were modified within the last 7 days — if a file is older than 7 days, it gets skipped.</p>
</li>
</ul>
<h4 id="12-the-process-of-getting-your-work-accepted">1.2 The process of getting your work accepted</h4>
<ul>
<li>First, review the codebase and existing issues to make sure I understand the basics of the project and avoid raising a duplicate issue.</li>
<li>Then, communicate with the repo owner — by Teams, by issue, by email, or whatever I like (but also must check the comfortable way for the owner first), to say, “hi, can I add a feature to your project, because…” The core of this is to “let them know.”</li>
<li>During the coding process, we’ll mainly communicate by the issue. I code, they give feedback, I change my code until we are all good for the issue.</li>
</ul>
<h3 id="2-technical-aspects">2. Technical aspects</h3>
<h4 id="21-how-did-file-timestamps-work-in-the-language-you-were-working-with">2.1 How did file timestamps work in the language you were working with?</h4>
<blockquote>
<p><a href="https://doc.rust-lang.org/std/fs/struct.Metadata.html#method.modified">https://doc.rust-lang.org/std/fs/struct.Metadata.html#method.modified</a></p>
</blockquote>
<p>According to this file metadata documentation, we have a lot of tools for obtaining info of a file, including the timestamps for the last modified time. Noticed that this method may “<strong>not be available on all platforms</strong>” so I added some error-handling code to it.</p>
<p>Next, we should also obtain the current system time (<a href="https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.now">https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.now</a>), minus 7 days, then compare these two variables. If the file wasn’t touched in 7 days, it is not a “recent” file.</p>
<h4 id="22-what-challenges-did-you-face-integrating-with-the-existing-codebase">2.2 What challenges did you face integrating with the existing codebase?</h4>
<p>I think there is one main challenge I want to mention: It takes time to understand the project.</p>
<p>I had to trace through the code to see how <code>clap</code> handles commands. Well… Actually I noticed soon that if I follow the coding pattern in the repo then I should be OK to write the new code. Fully understanding the <code>clap</code> is a hard task itself.</p>
<p>And I also need to figure out how the <code>Config</code> struct flows through the application (The really important task) and where the file processing logic lives in <code>file.rs</code>. Reading other people&rsquo;s code is always slower than writing your own, plus you have to spend a lot of time researching the language that you are not so familiar with.</p>
<h4 id="23-in-addition">2.3 In addition…</h4>
<p>In the process of collaboration, I do have a question I really want to ask: Should I use AI tools to quickly understand other people’s open-source projects?</p>
<p>Theoretically, feeding an open-source project into an AI shouldn’t pose security or legal issues, because it’s “open-source”; but, the AI technology is still so new (and the legal issues are always tricky) that no one really knows what the hidden costs might be. Even if I let the AI summarize someone else’s project, who can tell if its summary is reliable?</p>
<p>On the other hand, if I try to research and interpret things completely on my own, there’s still a high chance that I’ll make human mistakes. So, whether or not to use AI tools ends up becoming more of a “trade-off” decision to me…</p>
<h4 id="24-how-did-you-handle-edge-cases">2.4 How did you handle edge cases?</h4>
<p>There was an interesting thing I want to mention in testing. So when I implemented my feature and first tested it, I found that the app would output all the files in the target folder, which made me confused. But later I noticed that because:</p>
<ol>
<li>The target folder for testing is one of this project&rsquo;s folders.</li>
<li>When I use <code>git clone</code> to clone the repo to a local place, it also means that I “modified” all the local files in the folder.</li>
</ol>
<p>So, the “recent” feature will not filter anything out because all the files are “recently” edited. I think this case can be considered an edge case.</p>
<p>My solution is to manually create a <code>recent_test_files</code> folder that contains some old files and some new files, then test the feature on them. This leads to a correct test result and also prevents the application from reading too many unnecessary files at once.</p>
<h3 id="3-if-your-repo-received-a-pull-request">3. If your repo received a pull request…</h3>
<p>Haven’t got a PR yet. 😶‍🌫️</p>
]]></content:encoded></item><item><title>OSD600 Lab 1</title><link>https://www.parkerchenca.com/osd600/lab-1/</link><pubDate>Thu, 10 Sep 2026 11:29:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/lab-1/</guid><description>Blog about the process and outcomes for Lab 1</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:
Doing cool things with classmates</strong></p>
</blockquote>
<ul>
<li>How did you go about doing your code reviews? Do you prefer an async or sync approach? Why?</li>
</ul>
<p>I prefer the async approach to doing the code reviews; it gives me a flexible schedule to handle my work and life. And I feel relaxed when I need to read something alone.</p>
<ul>
<li>What was it like testing and reviewing someone else&rsquo;s code? Did you run into any problems? Did anything surprise you?</li>
</ul>
<p>Just like learning new concepts! I may know about the programming language, but the ideas from others are always new and valuable to me. I sometimes could not understand the meaning of others’ code, but thankfully, except for directly asking them, we can also leverage AI in these days.</p>
<ul>
<li>What was it like having someone test and review your code? Were you surprised by anything?</li>
</ul>
<p>It&rsquo;s just like being judged … but I considered it a little bit; in an open-source community, being reviewed by someone is for making the product better, and then I got relief with this thought. The collaborators always surprise me by discovering new bugs and applying new tests in a way that I never thought of before!</p>
<ul>
<li>What kind of issues came up in your testing and review? Discuss a few of them in detail.</li>
</ul>
<p>Well, for example, I got stuck in the middle when I tried to write tests for a C++ project (although I found that I don’t need to actually write them for this lab in the end). It doesn’t mean I don’t know about C++, but I need time to remind myself of how to write tests in C++ because it has been a while since I used C++ to build something. I have to search online for how to write the tests properly and look for examples. When I face some unfamiliar frameworks, testing and review take time.</p>
<ul>
<li>Provide links to issues you filed, and summarize what you found</li>
</ul>
<p><a href="https://github.com/ElshadHu/RepositoryContextManager/issues/3">https://github.com/ElshadHu/RepositoryContextManager/issues/3</a></p>
<p>This is a tricky one because I am not so familiar with CMakefile. When I tried to build the project the system kept showing errors, I had no idea at that time. But I finally found that it was triggered by the hardcoded PATH setting when I truly dove into the file. I want to tell myself, “If you want to fix a bug, don’t just stare at the error prompts, you have to dive into the file!”</p>
<p>All issues I filed should be under the same issues page; here is another repo I filed issues for: <a href="https://github.com/RiverDave/rust-cli-tool/issues">https://github.com/RiverDave/rust-cli-tool/issues</a></p>
<ul>
<li>Provide links to issues that were filed on your repo, and what they were about</li>
</ul>
<p><a href="https://github.com/BHChen24/repo2context/issues/1">https://github.com/BHChen24/repo2context/issues/1</a></p>
<p>And all other issues are under the “issues” page.</p>
<p>I noticed I included a configuration management tool in my project but since I haven’t used it, I didn’t write any comment or mention it in my “README.md”, and this did cause some confusion. Thanks a lot David!</p>
<ul>
<li>Were you able to fix all your issues? What was that like?</li>
</ul>
<p><a href="https://github.com/BHChen24/repo2context/issues/4">https://github.com/BHChen24/repo2context/issues/4</a></p>
<p>For documentation issues, I can, but for some feature requirements and tricky bugs I cannot yet. Actually, I fixed the markdown file syntax error immediately: the embedding link <code>[https://go.dev/](GO)</code> should be like <code>[Go](https://go.dev/)</code> .(And this is the first time I asked copilot to review my code for the PR, wow!)</p>
<ul>
<li>What did you learn through the process of doing the testing and reviewing?</li>
</ul>
<p>It’s definitely a necessary process for improving our products. The key point here is barely anyone can accomplish a high-quality project by working totally alone. In ancient China there is an idiom: “When everybody adds fuel, the flames rise high,” which means, “Great things can be achieved by mass effort.” This is a wonderful description of the meaning of testing and reviewing in the open-source community.</p>
]]></content:encoded></item><item><title>First post for OSD600</title><link>https://www.parkerchenca.com/osd600/first-post-for-osd600/</link><pubDate>Thu, 10 Sep 2026 11:28:00 +0000</pubDate><guid>https://www.parkerchenca.com/osd600/first-post-for-osd600/</guid><description>My introduction post for the OSD600 course in Seneca</description><content:encoded><![CDATA[<p>Hi, my name is Baihua Chen, but you can also call me Parker. You can find more information about me on my GitHub page at <a href="https://github.com/BHChen24">https://github.com/BHChen24</a> and on my personal website at <a href="https://www.parkerchenca.com/en/about">https://www.parkerchenca.com/en/about</a> .</p>
<p>Yes, I am taking the OSD600 course. To be honest, I have been very eager to take this course because many of my friends told me how valuable it is, and I have already felt the power of the open‑source community — I use Linux daily, I hear stories about open‑source projects and people all the time. In addition, I had never really thought too much about how open‑source projects can influence a company’s business before our first OSD600 lecture; that lecture really caught my interest.</p>
<p>I want to be someone who can confidently say “I am able to develop software for real‑world use” after this term, with open‑source contributing experience. I am especially interested in contributing to projects in the finance field, such as high‑precision computation, trading systems, backtesting systems, and so on.</p>
<p>I researched a project on the daily trend page called “everyone-can-use-english.” [<a href="https://github.com/ZuodaoTech/everyone-can-use-english/tree/main">https://github.com/ZuodaoTech/everyone-can-use-english/tree/main</a>] Since English is my second language, I often feel I am not good enough at using it. This project provides a way to improve my spoken English by correcting tone and pronunciation. For example, it has a feature called “Pronunciation Assessment,” which allows me to record my speaking and get feedback on whether it is correct, or how it can be improved.</p>
<p>I also noticed that its documentation is not very complete yet, and currently they only provide some demos in Chinese. Maybe these could be potential entry points for making contributions.</p>
]]></content:encoded></item><item><title>Daily Linux commands</title><link>https://www.parkerchenca.com/tech/daily-linux-commands/</link><pubDate>Thu, 10 Sep 2026 11:27:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/daily-linux-commands/</guid><description>Use Linux like the Windows</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:
With these commands you are able to do most text-related work the same as you are on Windows.</strong></p>
</blockquote>
<h2 id="linux-common-commands">Linux Common Commands</h2>
<h3 id="system-management">System Management</h3>
<h4 id="system-information">System Information</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Basic system information</span>
</span></span><span class="line"><span class="cl">lscpu                                  <span class="c1"># Detailed CPU information</span>
</span></span><span class="line"><span class="cl">uname -a                               <span class="c1"># Kernel and architecture info</span>
</span></span><span class="line"><span class="cl">cat /etc/os-release                    <span class="c1"># Distribution information</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Hardware information</span>
</span></span><span class="line"><span class="cl">lsblk                                  <span class="c1"># Block devices</span>
</span></span><span class="line"><span class="cl">lsusb                                  <span class="c1"># USB devices</span>
</span></span><span class="line"><span class="cl">lspci                                  <span class="c1"># PCI devices</span>
</span></span></code></pre></div><h4 id="package-management">Package Management</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># dpkg package management</span>
</span></span><span class="line"><span class="cl">sudo dpkg -i package.deb                           <span class="c1"># Install deb package</span>
</span></span><span class="line"><span class="cl">dpkg -l <span class="p">|</span> grep package_name                        <span class="c1"># Search installed packages</span>
</span></span><span class="line"><span class="cl">dpkg -L package_name                               <span class="c1"># List package files</span>
</span></span><span class="line"><span class="cl">dpkg -S /path/to/file                              <span class="c1"># Find which package owns file</span>
</span></span></code></pre></div><h3 id="monitoring-and-performance">Monitoring and Performance</h3>
<h4 id="memory-and-disk">Memory and Disk</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Memory usage</span>
</span></span><span class="line"><span class="cl">free -h                                <span class="c1"># Human readable format</span>
</span></span><span class="line"><span class="cl">watch -n <span class="m">1</span> free -h                     <span class="c1"># Real-time monitoring</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Disk usage</span>
</span></span><span class="line"><span class="cl">df -h                                  <span class="c1"># Disk usage</span>
</span></span><span class="line"><span class="cl">du -sh /path/to/directory              <span class="c1"># Directory size</span>
</span></span><span class="line"><span class="cl">du -h --max-depth<span class="o">=</span><span class="m">1</span> <span class="p">|</span> sort -hr         <span class="c1"># Sort directories by size</span>
</span></span><span class="line"><span class="cl">sudo fdisk -l                          <span class="c1"># Partition table info</span>
</span></span></code></pre></div><h4 id="system-monitoring">System Monitoring</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Temperature monitoring</span>
</span></span><span class="line"><span class="cl">vcgencmd measure_temp                   <span class="c1"># Raspberry Pi temperature</span>
</span></span><span class="line"><span class="cl">sensors                                <span class="c1"># General temperature sensors</span>
</span></span><span class="line"><span class="cl">watch -n <span class="m">1</span> vcgencmd measure_temp        <span class="c1"># Real-time temperature monitoring</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Process monitoring</span>
</span></span><span class="line"><span class="cl">ps aux                                 <span class="c1"># All processes</span>
</span></span><span class="line"><span class="cl">top                                    <span class="c1"># Real-time process monitor</span>
</span></span><span class="line"><span class="cl">htop                                   <span class="c1"># Enhanced top</span>
</span></span><span class="line"><span class="cl">ps aux --sort<span class="o">=</span>-%mem <span class="p">|</span> head -10         <span class="c1"># Sort by memory usage</span>
</span></span><span class="line"><span class="cl">ps aux --sort<span class="o">=</span>-%cpu <span class="p">|</span> head -10         <span class="c1"># Sort by CPU usage</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># I/O monitoring</span>
</span></span><span class="line"><span class="cl">sudo iotop                             <span class="c1"># I/O usage</span>
</span></span><span class="line"><span class="cl">sudo iotop -o                          <span class="c1"># Show only processes doing I/O</span>
</span></span></code></pre></div><h4 id="network-monitoring">Network Monitoring</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Connection status</span>
</span></span><span class="line"><span class="cl">ss -tuln                               <span class="c1"># Network connections</span>
</span></span><span class="line"><span class="cl">ss -a                                  <span class="c1"># All connections</span>
</span></span><span class="line"><span class="cl">ss -tuln <span class="p">|</span> grep :22                    <span class="c1"># Specific port</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Traffic monitoring</span>
</span></span><span class="line"><span class="cl">iftop                                  <span class="c1"># Interface traffic (requires installation)</span>
</span></span><span class="line"><span class="cl">nethogs                               <span class="c1"># Traffic by process (requires installation)</span>
</span></span></code></pre></div><h3 id="processes-and-services">Processes and Services</h3>
<h4 id="process-management">Process Management</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Find processes</span>
</span></span><span class="line"><span class="cl">pgrep -f <span class="s2">&#34;process_name&#34;</span>                <span class="c1"># Find process PID</span>
</span></span><span class="line"><span class="cl">ps aux <span class="p">|</span> grep <span class="s2">&#34;process_name&#34;</span>           <span class="c1"># Detailed information</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Terminate processes</span>
</span></span><span class="line"><span class="cl"><span class="nb">kill</span> PID                               <span class="c1"># Normal termination</span>
</span></span><span class="line"><span class="cl"><span class="nb">kill</span> -9 PID                            <span class="c1"># Force termination</span>
</span></span><span class="line"><span class="cl">pkill <span class="s2">&#34;process_name&#34;</span>                   <span class="c1"># Terminate by name</span>
</span></span></code></pre></div><h4 id="background-jobs">Background Jobs</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Background execution</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> <span class="p">&amp;</span>                              <span class="c1"># Start in background</span>
</span></span><span class="line"><span class="cl">nohup <span class="nb">command</span> <span class="p">&amp;</span>                        <span class="c1"># Run without hangup</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Job control</span>
</span></span><span class="line"><span class="cl">Ctrl + Z                               <span class="c1"># Suspend current process</span>
</span></span><span class="line"><span class="cl"><span class="nb">bg</span>                                     <span class="c1"># Continue in background</span>
</span></span><span class="line"><span class="cl"><span class="nb">fg</span>                                     <span class="c1"># Bring to foreground</span>
</span></span><span class="line"><span class="cl"><span class="nb">jobs</span>                                   <span class="c1"># List background jobs</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># tmux sessions</span>
</span></span><span class="line"><span class="cl">tmux new-session -d -s session_name <span class="s2">&#34;command&#34;</span>
</span></span><span class="line"><span class="cl">tmux attach -t session_name
</span></span></code></pre></div><h4 id="service-management">Service Management</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># systemd services</span>
</span></span><span class="line"><span class="cl">systemctl status service_name          <span class="c1"># Check status</span>
</span></span><span class="line"><span class="cl">systemctl start/stop/restart service_name
</span></span><span class="line"><span class="cl">systemctl enable/disable service_name  <span class="c1"># Auto-start on boot</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Log viewing</span>
</span></span><span class="line"><span class="cl">journalctl -u service_name             <span class="c1"># Service logs</span>
</span></span><span class="line"><span class="cl">journalctl -f                          <span class="c1"># Real-time logs</span>
</span></span><span class="line"><span class="cl">journalctl --since <span class="s2">&#34;2 hours ago&#34;</span>       <span class="c1"># Time range</span>
</span></span></code></pre></div><h4 id="scheduled-tasks">Scheduled Tasks</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># cron jobs</span>
</span></span><span class="line"><span class="cl">crontab -e                             <span class="c1"># Edit</span>
</span></span><span class="line"><span class="cl">crontab -l                             <span class="c1"># List</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Syntax: minute hour day month weekday command</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 0 2 * * * /home/user/backup.sh      # Run daily at 2 AM</span>
</span></span><span class="line"><span class="cl"><span class="c1"># */10 * * * * /usr/bin/check.sh      # Run every 10 minutes</span>
</span></span></code></pre></div><h3 id="network-management">Network Management</h3>
<h4 id="network-interfaces">Network Interfaces</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># View network interfaces</span>
</span></span><span class="line"><span class="cl">ip addr show                           <span class="c1"># All interfaces</span>
</span></span><span class="line"><span class="cl">ip a                                   <span class="c1"># Short form</span>
</span></span><span class="line"><span class="cl">ip link show up                        <span class="c1"># Enabled interfaces</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Manage interfaces</span>
</span></span><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> eth0 up/down          <span class="c1"># Enable/disable interface</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Routing information</span>
</span></span><span class="line"><span class="cl">ip route show                          <span class="c1"># Routing table</span>
</span></span><span class="line"><span class="cl">ip route <span class="p">|</span> grep default                <span class="c1"># Default gateway</span>
</span></span></code></pre></div><h4 id="wifi-management">WiFi Management</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># NetworkManager</span>
</span></span><span class="line"><span class="cl">nmcli dev wifi list                    <span class="c1"># Scan WiFi</span>
</span></span><span class="line"><span class="cl">nmcli dev wifi connect <span class="s2">&#34;SSID&#34;</span> password <span class="s2">&#34;password&#34;</span>
</span></span><span class="line"><span class="cl">nmcli connection show                  <span class="c1"># Saved connections</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Traditional tools</span>
</span></span><span class="line"><span class="cl">iwconfig                               <span class="c1"># WiFi interface status</span>
</span></span></code></pre></div><h4 id="network-testing">Network Testing</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Connectivity testing</span>
</span></span><span class="line"><span class="cl">ping google.com
</span></span><span class="line"><span class="cl">ping -c <span class="m">4</span> google.com                   <span class="c1"># Limit count</span>
</span></span><span class="line"><span class="cl">traceroute google.com                  <span class="c1"># Path tracing</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Port testing</span>
</span></span><span class="line"><span class="cl">nc -zv google.com <span class="m">80</span>                   <span class="c1"># Port connectivity</span>
</span></span><span class="line"><span class="cl">nmap -p 22,80,443 target_host          <span class="c1"># Port scanning</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># DNS queries</span>
</span></span><span class="line"><span class="cl">dig google.com                         <span class="c1"># DNS lookup</span>
</span></span><span class="line"><span class="cl">cat /etc/resolv.conf                   <span class="c1"># DNS configuration</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Firewall</span>
</span></span><span class="line"><span class="cl">sudo ufw status                        <span class="c1"># Ubuntu firewall status</span>
</span></span></code></pre></div><h3 id="files-and-text">Files and Text</h3>
<h4 id="file-finding">File Finding</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Find by name</span>
</span></span><span class="line"><span class="cl">find /path -name <span class="s2">&#34;filename&#34;</span>
</span></span><span class="line"><span class="cl">find . -name <span class="s2">&#34;*.txt&#34;</span>                   <span class="c1"># By extension</span>
</span></span><span class="line"><span class="cl">find . -type f -name <span class="s2">&#34;*.log&#34;</span>           <span class="c1"># Files only</span>
</span></span><span class="line"><span class="cl">find . -type d -name <span class="s2">&#34;temp*&#34;</span>           <span class="c1"># Directories only</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Command location</span>
</span></span><span class="line"><span class="cl">which python3                          <span class="c1"># Command location</span>
</span></span><span class="line"><span class="cl">whereis python3                        <span class="c1"># Binary, source, manual</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Fast search</span>
</span></span><span class="line"><span class="cl">sudo updatedb                          <span class="c1"># Update database</span>
</span></span><span class="line"><span class="cl">locate filename                        <span class="c1"># Quick search</span>
</span></span></code></pre></div><h4 id="content-search">Content Search</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Basic search</span>
</span></span><span class="line"><span class="cl">grep <span class="s2">&#34;pattern&#34;</span> file.txt
</span></span><span class="line"><span class="cl">grep <span class="s2">&#34;pattern&#34;</span> *.txt                   <span class="c1"># Multiple files</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Common options</span>
</span></span><span class="line"><span class="cl">grep -i <span class="s2">&#34;pattern&#34;</span> file                 <span class="c1"># Ignore case</span>
</span></span><span class="line"><span class="cl">grep -r <span class="s2">&#34;pattern&#34;</span> directory/           <span class="c1"># Recursive search</span>
</span></span><span class="line"><span class="cl">grep -n <span class="s2">&#34;pattern&#34;</span> file                 <span class="c1"># Show line numbers</span>
</span></span><span class="line"><span class="cl">grep -v <span class="s2">&#34;pattern&#34;</span> file                 <span class="c1"># Invert match</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Context search</span>
</span></span><span class="line"><span class="cl">grep -A <span class="m">3</span> <span class="s2">&#34;pattern&#34;</span> file               <span class="c1"># Show 3 lines after</span>
</span></span><span class="line"><span class="cl">grep -B <span class="m">3</span> <span class="s2">&#34;pattern&#34;</span> file               <span class="c1"># Show 3 lines before</span>
</span></span><span class="line"><span class="cl">grep -C <span class="m">3</span> <span class="s2">&#34;pattern&#34;</span> file               <span class="c1"># Show 3 lines around</span>
</span></span></code></pre></div><h4 id="file-content-operations">File Content Operations</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># View files</span>
</span></span><span class="line"><span class="cl">cat file.txt                           <span class="c1"># Full content</span>
</span></span><span class="line"><span class="cl">head -20 file.txt                      <span class="c1"># First 20 lines</span>
</span></span><span class="line"><span class="cl">tail -20 file.txt                      <span class="c1"># Last 20 lines</span>
</span></span><span class="line"><span class="cl">tail -f file.txt                       <span class="c1"># Follow changes</span>
</span></span><span class="line"><span class="cl">less file.txt                          <span class="c1"># Paged viewing</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Sort and unique</span>
</span></span><span class="line"><span class="cl">sort file.txt                          <span class="c1"># Sort</span>
</span></span><span class="line"><span class="cl">sort -n numbers.txt                    <span class="c1"># Numeric sort</span>
</span></span><span class="line"><span class="cl">sort file.txt <span class="p">|</span> uniq                   <span class="c1"># Remove duplicates</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># File comparison</span>
</span></span><span class="line"><span class="cl">diff file1.txt file2.txt               <span class="c1"># Basic comparison</span>
</span></span><span class="line"><span class="cl">diff -u file1 file2                    <span class="c1"># Unified format</span>
</span></span><span class="line"><span class="cl">diff -y file1 file2                    <span class="c1"># Side-by-side</span>
</span></span></code></pre></div><h4 id="text-processing-and-pipes">Text Processing and Pipes</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># sed stream editor</span>
</span></span><span class="line"><span class="cl">sed <span class="s1">&#39;s/old/new/g&#39;</span> file.txt             <span class="c1"># Global replacement</span>
</span></span><span class="line"><span class="cl">sed -i <span class="s1">&#39;s/old/new/g&#39;</span> file.txt          <span class="c1"># In-place modification</span>
</span></span><span class="line"><span class="cl">sed <span class="s1">&#39;/pattern/d&#39;</span> file.txt              <span class="c1"># Delete matching lines</span>
</span></span><span class="line"><span class="cl">sed -n <span class="s1">&#39;1,10p&#39;</span> file.txt                <span class="c1"># Print specific lines</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># awk text processing</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{print $1}&#39;</span> file.txt              <span class="c1"># Print first column</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{print $1, $3}&#39;</span> file.txt          <span class="c1"># Print multiple columns</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;/pattern/ {print $2}&#39;</span> file.txt    <span class="c1"># Conditional print</span>
</span></span><span class="line"><span class="cl">awk -F<span class="s1">&#39;:&#39;</span> <span class="s1">&#39;{print $1}&#39;</span> /etc/passwd     <span class="c1"># Specify delimiter</span>
</span></span><span class="line"><span class="cl">awk <span class="s1">&#39;{sum += $1} END {print sum}&#39;</span> numbers.txt  <span class="c1"># Calculate sum</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Pipes and redirection</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> &gt; file.txt                     <span class="c1"># Output redirection</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> &gt;&gt; file.txt                    <span class="c1"># Append redirection</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> 2&gt; error.log                   <span class="c1"># Error redirection</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> <span class="p">&amp;</span>&gt; all.log                     <span class="c1"># All output redirection</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Pipe operations</span>
</span></span><span class="line"><span class="cl">command1 <span class="p">|</span> command2                    <span class="c1"># Basic pipe</span>
</span></span><span class="line"><span class="cl">cat log <span class="p">|</span> grep <span class="s2">&#34;ERROR&#34;</span> <span class="p">|</span> awk <span class="s1">&#39;{print $1}&#39;</span> <span class="p">|</span> sort <span class="p">|</span> uniq -c
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># tee splitting</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> <span class="p">|</span> tee file.txt                 <span class="c1"># Output to both file and terminal</span>
</span></span><span class="line"><span class="cl"><span class="nb">command</span> <span class="p">|</span> tee -a file.txt              <span class="c1"># Append mode</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;text&#34;</span> <span class="p">|</span> sudo tee /root/file.txt &gt; /dev/null  <span class="c1"># Privilege escalation write</span>
</span></span></code></pre></div><h3 id="transfer-and-compression">Transfer and Compression</h3>
<h4 id="network-downloads">Network Downloads</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># wget downloads</span>
</span></span><span class="line"><span class="cl">wget https://example.com/file.zip
</span></span><span class="line"><span class="cl">wget -O newname.zip https://example.com/file.zip  <span class="c1"># Specify filename</span>
</span></span><span class="line"><span class="cl">wget -c https://example.com/largefile.iso         <span class="c1"># Resume download</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># curl downloads</span>
</span></span><span class="line"><span class="cl">curl -O https://example.com/file.zip               <span class="c1"># Keep original filename</span>
</span></span><span class="line"><span class="cl">curl -o newname.zip https://example.com/file.zip   <span class="c1"># Specify filename</span>
</span></span><span class="line"><span class="cl">curl -C - -O https://example.com/largefile.iso     <span class="c1"># Resume download</span>
</span></span></code></pre></div><h4 id="remote-transfer">Remote Transfer</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># scp secure copy</span>
</span></span><span class="line"><span class="cl">scp file.txt user@remote:/path/                    <span class="c1"># Upload file</span>
</span></span><span class="line"><span class="cl">scp -r directory/ user@remote:/path/               <span class="c1"># Upload directory</span>
</span></span><span class="line"><span class="cl">scp user@remote:/path/file.txt ./                  <span class="c1"># Download file</span>
</span></span><span class="line"><span class="cl">scp -P <span class="m">2222</span> file.txt user@remote:/path/            <span class="c1"># Specify port</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># rsync synchronization</span>
</span></span><span class="line"><span class="cl">rsync -av source/ destination/                     <span class="c1"># Basic sync</span>
</span></span><span class="line"><span class="cl">rsync -av --delete source/ destination/            <span class="c1"># Delete extra files</span>
</span></span><span class="line"><span class="cl">rsync -av source/ user@remote:/path/               <span class="c1"># Remote sync</span>
</span></span><span class="line"><span class="cl">rsync -avz --progress source/ destination/         <span class="c1"># Compression + progress</span>
</span></span></code></pre></div><h4 id="compression-and-extraction">Compression and Extraction</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># tar archives</span>
</span></span><span class="line"><span class="cl">tar -czf archive.tar.gz files/                     <span class="c1"># Create compressed archive</span>
</span></span><span class="line"><span class="cl">tar -xzf archive.tar.gz                            <span class="c1"># Extract archive</span>
</span></span><span class="line"><span class="cl">tar -tzf archive.tar.gz                            <span class="c1"># View contents</span>
</span></span><span class="line"><span class="cl">tar -xzf archive.tar.gz -C /destination/           <span class="c1"># Extract to directory</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># zip compression</span>
</span></span><span class="line"><span class="cl">zip -r archive.zip directory/                      <span class="c1"># Compress directory</span>
</span></span><span class="line"><span class="cl">unzip archive.zip                                  <span class="c1"># Extract</span>
</span></span><span class="line"><span class="cl">unzip archive.zip -d /destination/                 <span class="c1"># Extract to directory</span>
</span></span><span class="line"><span class="cl">unzip -l archive.zip                               <span class="c1"># View contents</span>
</span></span></code></pre></div><h3 id="device-management">Device Management</h3>
<h4 id="usb-devices">USB Devices</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># USB device management</span>
</span></span><span class="line"><span class="cl">lsusb                                  <span class="c1"># USB device list</span>
</span></span><span class="line"><span class="cl">lsusb -v                               <span class="c1"># Detailed information</span>
</span></span><span class="line"><span class="cl">watch -n <span class="m">1</span> lsusb                       <span class="c1"># Real-time monitoring</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Mount USB</span>
</span></span><span class="line"><span class="cl">sudo mkdir /mnt/usb
</span></span><span class="line"><span class="cl">sudo mount /dev/sdb1 /mnt/usb          <span class="c1"># Mount</span>
</span></span><span class="line"><span class="cl">sudo umount /mnt/usb                   <span class="c1"># Unmount</span>
</span></span></code></pre></div><h4 id="bluetooth-devices">Bluetooth Devices</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Bluetooth management</span>
</span></span><span class="line"><span class="cl">systemctl status bluetooth             <span class="c1"># Service status</span>
</span></span><span class="line"><span class="cl">sudo hciconfig hci0 up                 <span class="c1"># Enable adapter</span>
</span></span><span class="line"><span class="cl">sudo hcitool scan                      <span class="c1"># Scan devices</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Bluetooth console</span>
</span></span><span class="line"><span class="cl">bluetoothctl
</span></span><span class="line"><span class="cl"><span class="c1"># Common commands: power on, scan on, pair &lt;MAC&gt;, connect &lt;MAC&gt;</span>
</span></span></code></pre></div><h4 id="audio-devices">Audio Devices</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Audio devices</span>
</span></span><span class="line"><span class="cl">aplay -l                               <span class="c1"># Playback devices</span>
</span></span><span class="line"><span class="cl">arecord -l                             <span class="c1"># Recording devices</span>
</span></span><span class="line"><span class="cl">pactl list sinks short                 <span class="c1"># PulseAudio output devices</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Volume control</span>
</span></span><span class="line"><span class="cl">alsamixer                              <span class="c1"># Graphical mixer</span>
</span></span><span class="line"><span class="cl">amixer sset Master 80%                 <span class="c1"># Set volume</span>
</span></span><span class="line"><span class="cl">pactl set-sink-volume @DEFAULT_SINK@ 50%
</span></span></code></pre></div><h3 id="quick-operations">Quick Operations</h3>
<h4 id="history-operations">History Operations</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># History search</span>
</span></span><span class="line"><span class="cl">Ctrl + R                               <span class="c1"># Reverse search history</span>
</span></span><span class="line"><span class="cl">Ctrl + S                               <span class="c1"># Forward search history</span>
</span></span><span class="line"><span class="cl"><span class="nb">history</span>                                <span class="c1"># Show history list</span>
</span></span><span class="line"><span class="cl"><span class="nb">history</span> <span class="p">|</span> grep <span class="s2">&#34;pattern&#34;</span>               <span class="c1"># Search history commands</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ! operator (history expansion)</span>
</span></span><span class="line"><span class="cl">!!                                     <span class="c1"># Repeat last command</span>
</span></span><span class="line"><span class="cl">!$                                     <span class="c1"># Last argument of previous command</span>
</span></span><span class="line"><span class="cl">!^                                     <span class="c1"># First argument of previous command</span>
</span></span><span class="line"><span class="cl">!*                                     <span class="c1"># All arguments of previous command</span>
</span></span><span class="line"><span class="cl">!n                                     <span class="c1"># Execute nth command in history</span>
</span></span><span class="line"><span class="cl">!ssh                                   <span class="c1"># Execute most recent command starting with ssh</span>
</span></span><span class="line"><span class="cl">!?config                               <span class="c1"># Execute most recent command containing config</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Quick substitution</span>
</span></span><span class="line"><span class="cl">^old^new                               <span class="c1"># Replace old with new in last command</span>
</span></span><span class="line"><span class="cl">!!:s/old/new                           <span class="c1"># Same as above, sed-style replacement</span>
</span></span><span class="line"><span class="cl">sudo !!                                <span class="c1"># Add sudo to previous command</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Argument operations</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> !$                                <span class="c1"># Show last argument of previous command</span>
</span></span><span class="line"><span class="cl">ls !*                                  <span class="c1"># Use all arguments from previous command with ls</span>
</span></span></code></pre></div><h4 id="quick-editing">Quick Editing</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Cursor movement</span>
</span></span><span class="line"><span class="cl">Ctrl + A                               <span class="c1"># Move to beginning of line</span>
</span></span><span class="line"><span class="cl">Ctrl + E                               <span class="c1"># Move to end of line</span>
</span></span><span class="line"><span class="cl">Ctrl + F                               <span class="c1"># Move forward one character</span>
</span></span><span class="line"><span class="cl">Ctrl + B                               <span class="c1"># Move backward one character</span>
</span></span><span class="line"><span class="cl">Alt + F                                <span class="c1"># Move forward one word</span>
</span></span><span class="line"><span class="cl">Alt + B                                <span class="c1"># Move backward one word</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Deletion operations</span>
</span></span><span class="line"><span class="cl">Ctrl + K                               <span class="c1"># Delete from cursor to end of line</span>
</span></span><span class="line"><span class="cl">Ctrl + U                               <span class="c1"># Delete from cursor to beginning of line</span>
</span></span><span class="line"><span class="cl">Ctrl + W                               <span class="c1"># Delete previous word</span>
</span></span><span class="line"><span class="cl">Alt + D                                <span class="c1"># Delete next word</span>
</span></span><span class="line"><span class="cl">Ctrl + H                               <span class="c1"># Delete previous character (same as Backspace)</span>
</span></span><span class="line"><span class="cl">Ctrl + D                               <span class="c1"># Delete current character</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Copy and paste</span>
</span></span><span class="line"><span class="cl">Ctrl + Y                               <span class="c1"># Paste last deleted content</span>
</span></span><span class="line"><span class="cl">Alt + Y                                <span class="c1"># Cycle through deletion history</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Other editing</span>
</span></span><span class="line"><span class="cl">Ctrl + T                               <span class="c1"># Transpose current and previous character</span>
</span></span><span class="line"><span class="cl">Alt + T                                <span class="c1"># Transpose current and previous word</span>
</span></span><span class="line"><span class="cl">Alt + U                                <span class="c1"># Convert current word to uppercase</span>
</span></span><span class="line"><span class="cl">Alt + L                                <span class="c1"># Convert current word to lowercase</span>
</span></span><span class="line"><span class="cl">Alt + C                                <span class="c1"># Capitalize current word</span>
</span></span><span class="line"><span class="cl">Ctrl + _                               <span class="c1"># Undo last edit</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># System control</span>
</span></span><span class="line"><span class="cl">Ctrl + L                               <span class="c1"># Clear screen</span>
</span></span><span class="line"><span class="cl">Ctrl + C                               <span class="c1"># Interrupt current command</span>
</span></span><span class="line"><span class="cl">Ctrl + Z                               <span class="c1"># Suspend current process</span>
</span></span><span class="line"><span class="cl">Ctrl + D                               <span class="c1"># End input/exit shell</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Auto-completion</span>
</span></span><span class="line"><span class="cl">Tab                                    <span class="c1"># Auto-complete</span>
</span></span><span class="line"><span class="cl">Tab Tab                                <span class="c1"># Show all possible completions</span>
</span></span><span class="line"><span class="cl">Alt + .                                <span class="c1"># Insert last argument of previous command</span>
</span></span><span class="line"><span class="cl">Alt + *                                <span class="c1"># Expand all possible completions for current word</span>
</span></span></code></pre></div><h4 id="directory-and-file-operations">Directory and File Operations</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Directory operations</span>
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> -                                   <span class="c1"># Return to previous directory</span>
</span></span><span class="line"><span class="cl">pushd/popd                             <span class="c1"># Directory stack operations</span>
</span></span><span class="line"><span class="cl">mkdir -p path/to/deep/directory        <span class="c1"># Create nested directories</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># {} Brace expansion - generates multiple names</span>
</span></span><span class="line"><span class="cl">touch file<span class="o">{</span>1,2,3<span class="o">}</span>.txt                  <span class="c1"># Creates file1.txt file2.txt file3.txt</span>
</span></span><span class="line"><span class="cl">mkdir <span class="o">{</span>backup,temp,logs<span class="o">}</span>               <span class="c1"># Create multiple directories</span>
</span></span><span class="line"><span class="cl">cp file.txt<span class="o">{</span>,.bak<span class="o">}</span>                     <span class="c1"># Copy to file.txt.bak</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="o">{</span>A..Z<span class="o">}</span>                           <span class="c1"># Expand A B C ... Z</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="o">{</span>1..10<span class="o">}</span>                          <span class="c1"># Expand 1 2 3 ... 10</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="o">{</span>01..10<span class="o">}</span>                         <span class="c1"># Expand 01 02 03 ... 10 (preserve format)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># [] Bracket matching - matches existing files</span>
</span></span><span class="line"><span class="cl">ls file<span class="o">[</span>123<span class="o">]</span>.txt                       <span class="c1"># Match file1.txt file2.txt file3.txt</span>
</span></span><span class="line"><span class="cl">ls file<span class="o">[</span>1-5<span class="o">]</span>.txt                       <span class="c1"># Match file1.txt to file5.txt</span>
</span></span><span class="line"><span class="cl">ls <span class="o">[</span>abc<span class="o">]</span>*.txt                          <span class="c1"># Match txt files starting with a, b, or c</span>
</span></span><span class="line"><span class="cl">ls <span class="o">[</span>A-Z<span class="o">]</span>*.log                          <span class="c1"># Match log files starting with uppercase</span>
</span></span><span class="line"><span class="cl">ls file<span class="o">[</span>!123<span class="o">]</span>.txt                      <span class="c1"># Match files except file1,2,3.txt</span>
</span></span><span class="line"><span class="cl">rm temp<span class="o">[</span>0-9<span class="o">][</span>0-9<span class="o">]</span>.tmp                  <span class="c1"># Delete files like temp01.tmp to temp99.tmp</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Wildcard combinations</span>
</span></span><span class="line"><span class="cl">cp *.<span class="o">{</span>jpg,png,gif<span class="o">}</span> images/             <span class="c1"># Copy all image files</span>
</span></span><span class="line"><span class="cl">ls file<span class="o">[</span>1-3<span class="o">]</span>.<span class="o">{</span>txt,log<span class="o">}</span>                 <span class="c1"># Match file1.txt, file1.log, etc.</span>
</span></span><span class="line"><span class="cl">find . -name <span class="s2">&#34;*[0-9].txt&#34;</span>              <span class="c1"># Find txt files ending with digits</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>Result and Option in short</title><link>https://www.parkerchenca.com/tech/result-and-option-in-short/</link><pubDate>Thu, 10 Sep 2026 11:26:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/result-and-option-in-short/</guid><description>Two old friends in Rust</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
When writing Rust programs, Result and Option are data structures we can hardly avoid. I believe that rather than understanding their underlying mechanisms, we should first quickly figure out how to handle them.</p>
</blockquote>
<h2 id="gift-wrapping">Gift Wrapping</h2>
<p>Actually, we don&rsquo;t need to think of <code>Option&lt;T&gt;</code> and <code>Result&lt;T,E&gt;</code> as too complicated:</p>
<ul>
<li><code>Option</code> contains the data we want, where the data type is <code>T</code>. However, there might be no data inside (<code>None</code>). But regardless, as long as what we care about is wrapped, it <strong>will be</strong> an <code>Option</code>.</li>
<li><code>Result</code> also contains the data we want, but it comes with another &ldquo;restless&rdquo; additional item <code>E</code> (Error). In fact, combinations of Result and Option are very common, such as <code>Result&lt;Option&lt;T&gt;, E&gt;</code>. <code>Result</code> provides a powerful and <strong>unified</strong> specification for Rust&rsquo;s error handling.</li>
</ul>
<h3 id="so-how-do-we-open-the-gift-box">So, how do we open the gift box&hellip;</h3>
<p>The moment of unwrapping gifts is always exciting.</p>
<p>Whether it&rsquo;s <code>Option</code> or <code>Result</code>, we can use <code>unwrap()</code> to open this package.</p>
<ul>
<li>If the gift box contains a normal value, everything goes smoothly, and everyone&rsquo;s happy.</li>
<li>But if it contains something &ldquo;weird&rdquo; (<code>None</code> or <code>Err</code>), the program will immediately <code>panic</code> and crash.</li>
</ul>
<p>Of course, if we insist on using safer unwrapping methods (like <code>unwrap_or</code>, <code>match</code>, etc.), we can control whether the program crashes ourselves, which is very practical.</p>
<h3 id="what-functions-do-these-gift-boxes-provide">What functions do these gift boxes provide?</h3>
<p>Let&rsquo;s quickly go through the methods they provide. Detailed explanations won&rsquo;t be provided here, as I believe you can look up relevant information through <a href="https://doc.rust-lang.org/std/option/">https://doc.rust-lang.org/std/option/</a> and <a href="https://doc.rust-lang.org/std/result/">https://doc.rust-lang.org/std/result/</a>.</p>
<h4 id="option">Option</h4>
<table>
	<thead>
			<tr>
					<th>API</th>
					<th>Purpose</th>
					<th>Return Value and Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>is_some()</code></td>
					<td>Check if it&rsquo;s <code>Some</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>is_none()</code></td>
					<td>Check if it&rsquo;s <code>None</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>unwrap()</code></td>
					<td>Get the value inside <code>Some</code>, panic if <code>None</code></td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or(default)</code></td>
					<td>Get value, return specified default if <code>None</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or_else(f)</code></td>
					<td>Get value, call closure <code>f</code> to return default if <code>None</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>map(f)</code></td>
					<td>If <code>Some</code>, call <code>f</code> on inner value, return new <code>Option</code></td>
					<td><code>Option&lt;U&gt;</code></td>
			</tr>
			<tr>
					<td><code>and_then(f)</code></td>
					<td>If <code>Some</code>, call <code>f</code>, return another <code>Option</code></td>
					<td><code>Option&lt;U&gt;</code></td>
			</tr>
			<tr>
					<td><code>or(other)</code></td>
					<td>If <code>None</code>, return parameter <code>other</code>, otherwise return self</td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>or_else(f)</code></td>
					<td>If <code>None</code>, call closure <code>f</code> to return an <code>Option</code></td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_ref()</code></td>
					<td>Convert <code>Option&lt;T&gt;</code> to immutable reference of inner value <code>Option&lt;&amp;T&gt;</code></td>
					<td><code>Option&lt;&amp;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_mut()</code></td>
					<td>Convert <code>Option&lt;T&gt;</code> to mutable reference of inner value <code>Option&lt;&amp;mut T&gt;</code></td>
					<td><code>Option&lt;&amp;mut T&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok_or(err)</code></td>
					<td>Convert <code>Some(value)</code> to <code>Ok(value)</code>, and <code>None</code> to <code>Err(err)</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok_or_else(f)</code></td>
					<td>Same as above, but call closure if <code>None</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>expect(msg)</code></td>
					<td>Similar to <code>unwrap()</code>, but allows custom error message</td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>?</code></td>
					<td>Return <code>None</code> directly when <code>None</code> (must be used in functions returning <code>Option</code>)</td>
					<td><code>T</code> / early return</td>
			</tr>
	</tbody>
</table>
<p>Notable methods:</p>
<ul>
<li><code>map(f)</code> provides a way to operate on inner data without unpacking, very commonly used</li>
<li><code>expect(&quot;Hi&quot;)</code> can display error messages when panicking, more practical than <code>unwrap()</code></li>
<li><code>?</code> can greatly improve code cleanliness</li>
<li><code>is_some()</code> and <code>is_none()</code> are also very useful for making decisions</li>
</ul>
<h3 id="result">Result</h3>
<p>Compared to the intuitive and easy-to-understand <code>Option</code>, <code>Result</code> seems more &ldquo;convoluted&rdquo; with an additional type, but essentially it&rsquo;s almost identical to <code>Option</code>: what to do if we didn&rsquo;t get the value (possibly due to an error).</p>
<table>
	<thead>
			<tr>
					<th>API</th>
					<th>Purpose</th>
					<th>Return Value / Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>is_ok()</code></td>
					<td>Check if it&rsquo;s <code>Ok</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>is_err()</code></td>
					<td>Check if it&rsquo;s <code>Err</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>unwrap()</code></td>
					<td>Get value inside <code>Ok</code>, <code>panic</code> if <code>Err</code></td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or(default)</code></td>
					<td>Get value, return default if <code>Err</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or_else(f)</code></td>
					<td>Get value, call closure <code>f</code> to return default if <code>Err</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>map(f)</code></td>
					<td>If <code>Ok</code>, call <code>f</code> on inner value, return new <code>Result</code></td>
					<td><code>Result&lt;U, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>and_then(f)</code></td>
					<td>If <code>Ok</code>, call <code>f</code>, return another <code>Result</code></td>
					<td><code>Result&lt;U, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>map_err(f)</code></td>
					<td>If <code>Err</code>, call <code>f</code> on error, return new <code>Result</code></td>
					<td><code>Result&lt;T, F&gt;</code></td>
			</tr>
			<tr>
					<td><code>or(other)</code></td>
					<td>If <code>Err</code>, return <code>other</code>, otherwise return self</td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>or_else(f)</code></td>
					<td>If <code>Err</code>, call closure <code>f</code> to return <code>Result</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_ref()</code></td>
					<td>Convert to immutable references</td>
					<td><code>Result&lt;&amp;T, &amp;E&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_mut()</code></td>
					<td>Convert to mutable references</td>
					<td><code>Result&lt;&amp;mut T, &amp;mut E&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok()</code></td>
					<td>Success value → <code>Some(value)</code>, error → <code>None</code></td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>err()</code></td>
					<td>Error value → <code>Some(error)</code>, success → <code>None</code></td>
					<td><code>Option&lt;E&gt;</code></td>
			</tr>
			<tr>
					<td><code>expect(msg)</code></td>
					<td>Similar to <code>unwrap()</code>, but allows custom error message</td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>?</code></td>
					<td>Return early when encountering <code>Err</code> (must be used in functions returning <code>Result</code>)</td>
					<td><code>T</code> / early return</td>
			</tr>
	</tbody>
</table>
<p><code>Result</code> also has: <code>map(f)</code> and <code>?</code>, as well as useful <code>is_ok()</code> and <code>is_err()</code></p>
<p>In <code>Result&lt;T, E&gt;</code>:</p>
<ul>
<li><code>T</code> is the type of value returned on success (e.g., file content, calculation result, etc.).</li>
<li><code>E</code> is the type of value returned on error (e.g., <code>std::io::Error</code>, custom error <code>enum</code>, etc.).</li>
<li>Actually:
<ul>
<li><code>E</code> can be any type, with no restrictions</li>
<li>But to use <code>?</code>, facilitate debugging and printing, <code>E</code> usually needs to implement <code>Debug</code>, <code>Display</code>, <code>Error</code>, and other traits</li>
<li>Yes, <code>E</code> can be very complex types (carrying context, providing helper methods), or very simple error structures (like, a string). <code>Err</code> is just the shell that <code>Result</code> uses to mark &ldquo;this is the error branch&rdquo;, with <code>E</code> inside</li>
</ul>
</li>
</ul>
<h3 id="examples">Examples</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="c1">// ===== Creating Option =====
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">some_value</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span><span class="w">  </span><span class="c1">// Has value
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">none_value</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">None</span><span class="p">;</span><span class="w">      </span><span class="c1">// No value
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage: returning from functions
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">find_number</span><span class="p">(</span><span class="n">flag</span>: <span class="kt">bool</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// ===== Creating Result =====
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">ok_value</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span><span class="w">                    </span><span class="c1">// Success
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">err_value</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="s">&#34;Oops&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">());</span><span class="w"> </span><span class="c1">// Failure
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage: returning from functions
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">divide</span><span class="p">(</span><span class="n">a</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Err</span><span class="p">(</span><span class="s">&#34;Division by zero&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Ok</span><span class="p">(</span><span class="n">a</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Vim in (not so) short</title><link>https://www.parkerchenca.com/tech/vim-in-not-so-short/</link><pubDate>Thu, 10 Sep 2026 11:25:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/vim-in-not-so-short/</guid><description>I want to make it short, but Vim is too powerful</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Yes, You can always type :h to see help, for example, :h windows</p>
</blockquote>
<h2 id="vim-in-not-so-short"><strong>Vim in not so short</strong></h2>
<h3 id="preliminaries">Preliminaries</h3>
<ul>
<li>When vim is not available, you can temporarily use <code>cat</code> or <code>nano</code> as alternatives</li>
<li>When using a new IDE, you should first learn or configure:
<ul>
<li>save</li>
<li>copy / paste</li>
<li>duplicate line</li>
<li>delete word / delete line</li>
<li>line movement</li>
<li>navigate forward / back</li>
<li>undo / redo</li>
<li>page navigation (page down, page up, center to middle, etc.)</li>
<li>indent / unindent</li>
<li>multi-cursor</li>
<li>search / content search</li>
<li>input commands (<code>Ctrl + P</code> in VSCode, double <code>Shift</code> in IntelliJ, <code>:</code> in vim…)</li>
<li>completion, suggestion, parameter hint, hover hint</li>
<li>go to / peek definition, type, declaration, reference, implementation</li>
<li>rename symbol / refactor (if available)</li>
<li>AI controlling: toggle chat box, trigger inline chat…</li>
<li>tabs / windows management</li>
</ul>
</li>
<li>Use the <code>:help</code> command to query anything you don’t understand</li>
<li><code>:set option?</code> can view current settings</li>
</ul>
<hr>
<h3 id="windows-and-tabs">Windows and Tabs</h3>
<p><strong>Buffer:</strong> Can be understood as a temporary file. Even if this file is edited, it doesn’t mean it’s written to the actual file. We can <strong>observe</strong> buffers through windows and <strong>manage</strong> them through tabs.</p>
<ol>
<li>Use commands starting with <code>b</code> in Ex (command line) mode for buffer operations:
<ul>
<li><code>bd</code> buffer delete; <code>bwipeout</code> clears more thoroughly</li>
<li><code>bn</code> or <code>bnext</code> switch to next buffer</li>
<li><code>bp</code> or <code>bprevious</code> switch to previous buffer</li>
<li><code>ctrl + ^</code>  switch to the last buffer</li>
</ul>
</li>
</ol>
<p><code>Ctrl + W</code> window shortcuts and <code>:sp</code> split commands are the basics of window management. <code>:sp</code> can use parameters to specify files to split (open a new window for this file)</p>
<ol>
<li><code>Ctrl + W</code> + <code>w</code> cycle windows, <code>Ctrl + W</code> + <code>hjkl</code> switch focus left/down/up/right (move cursor)</li>
<li><code>Ctrl + W</code> + <code>=</code> (make window panes equal size)</li>
<li><code>Ctrl + W</code> + <code>+</code> <code>Ctrl + W</code> +  <code>Ctrl + W</code> + <code>&lt;</code> <code>Ctrl + W</code> + <code>&gt;</code> (fine-tune window size)</li>
<li><code>:vsp</code> performs vertical split, dividing into two sides</li>
<li><code>:resize 20</code> sets height to 20 lines; <code>:vertical resize 80</code> sets width to 80 columns</li>
</ol>
<p><code>:tabs</code> is the basic tab management command.</p>
<ol>
<li><code>:tabnew</code> opens a new tab, <code>:tabe</code> (edit) opens a tab for editing. Can be followed by filename.</li>
<li><code>:tabn</code> <code>:tabp</code> switch tabs, or use <code>gt</code> <code>gT</code> to switch</li>
<li>Display current buffer in new tab: <code>:tab split</code></li>
<li><code>:tabmove</code> move tab, for example <code>:tabmove 2</code></li>
<li><strong>Batch execution</strong>:
<ul>
<li><code>:tabdo {cmd}</code> execute on all tabs, e.g., <code>:tabdo set nocursorline</code></li>
<li><code>:windo {cmd}</code> execute on each window in current tab, e.g., <code>:windo diffthis</code></li>
</ul>
</li>
</ol>
<p><code>:only</code> and <code>:close</code> are universal management methods</p>
<ol>
<li>Type <code>:close</code> <code>:only</code> directly to manage windows</li>
<li>Type <code>:tabclose</code> <code>:tabonly</code> to manage tabs</li>
</ol>
<hr>
<h3 id="key-remapping">Key Remapping</h3>
<p>Here’s the key remapping configuration in VSCode vim extension:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.leader&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;space&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.useSystemClipboard&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// important
</span></span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.normalModeKeyBindings&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;J&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;5&#34;</span><span class="p">,</span> <span class="s2">&#34;j&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;K&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;5&#34;</span><span class="p">,</span> <span class="s2">&#34;k&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.normalModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&lt;Backspace&gt;&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;x&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.insertModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.visualModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&lt;Backspace&gt;&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;d&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Common key aliases:</p>
<ul>
<li><code>&lt;Backspace&gt;</code></li>
<li><code>&lt;C-c&gt;</code> -&gt; Ctrl + C</li>
<li><code>&lt;A-c&gt;</code> -&gt; Alt + C</li>
<li><code>&lt;Shift&gt;</code></li>
<li><code>&lt;CapsLock&gt;</code></li>
<li><code>&lt;Tab&gt;</code></li>
<li><code>&lt;Enter&gt;</code></li>
<li><code>&lt;Esc&gt;</code></li>
<li><code>&lt;Cmd-&gt;</code> Mac specific</li>
<li><code>&lt;Up&gt;</code></li>
<li><code>&lt;Down&gt;</code></li>
<li><code>&lt;Left&gt;</code></li>
<li><code>&lt;Right&gt;</code></li>
</ul>
<hr>
<h4 id="vim-configuration-file">vim Configuration File</h4>
<p>Use the <code>.vimrc</code> file in the <code>home</code> directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-mysql" data-lang="mysql"><span class="line"><span class="cl"><span class="s2">&#34; This is vimscript, so use let for assignment and &#34;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">comments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="o">&lt;</span><span class="n">SPACE</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&lt;</span><span class="n">Nop</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">let</span><span class="w"> </span><span class="n">mapleader</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&#34; &#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">set</span><span class="w"> </span><span class="n">number</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; Use system clipboard
</span></span></span><span class="line"><span class="cl"><span class="s2">set clipboard=unnamedplus
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">Map</span><span class="w"> </span><span class="o">`</span><span class="n">J</span><span class="o">`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="mi">5</span><span class="n">j</span><span class="o">`</span><span class="p">,</span><span class="w"> </span><span class="o">`</span><span class="n">K</span><span class="o">`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="mi">5</span><span class="n">k</span><span class="o">`</span><span class="p">,</span><span class="w"> </span><span class="o">`&lt;</span><span class="n">Backspace</span><span class="o">&gt;`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="n">x</span><span class="o">`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="mi">5</span><span class="n">j</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="mi">5</span><span class="n">k</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="o">&lt;</span><span class="n">Backspace</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; inoremap
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">vnoremap</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; nmap
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">imap</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; vmap
</span></span></span><span class="line"><span class="cl"><span class="s2">nnoremap &lt;Enter&gt; o&lt;Esc&gt;
</span></span></span></code></pre></div><hr>
<h3 id="unbound-keys">Unbound Keys</h3>
<p>In VSCode and other IDEs, you can return Vim-controlled keys to the IDE, since they have no use in GUI interfaces.</p>
<ul>
<li><code>Ctrl + D</code> scroll down</li>
<li><code>Ctrl + Z</code> suspend Vim</li>
<li><code>Ctrl + X</code> decrease number at cursor by 1, in insert mode it’s completion, decrease by 1 is quite useful</li>
<li><code>Ctrl + C</code> can be considered</li>
<li><code>Ctrl + F</code> scroll forward, in insert mode used to view command history</li>
<li><code>Ctrl + W</code> window command, delete one word before cursor</li>
<li><code>Ctrl + P</code> completion</li>
<li><code>Ctrl + S</code> pause output</li>
<li><code>Ctrl + Q</code> same as <code>Ctrl + V</code>, only <code>q</code> alone is for recording macros, VSCode defaults to <em>Add cursor below</em>, multi-cursor editing tool</li>
<li><code>Ctrl + Y / E</code> scroll window up/down by 1 line</li>
<li><code>Ctrl + T</code> depends on situation</li>
</ul>
<hr>
<h3 id="quick-reference">Quick Reference</h3>
<p><strong>(jut for memory, may not be accurate)</strong></p>
<ol>
<li><code>w</code> -&gt; word</li>
<li><code>b</code> -&gt; back</li>
<li><code>e</code> -&gt; end</li>
<li><code>H</code> -&gt; page head; <code>L</code> -&gt; low; <code>M</code> -&gt; middle</li>
<li><code>zz</code> move current line to the middle position</li>
<li><code>Ctrl + U</code> &amp; <code>Ctrl + D</code> half screen move up &amp; down
<ul>
<li><code>Ctrl + F</code> &amp; <code>Ctrl + B</code> full screen move forward &amp; back</li>
</ul>
</li>
<li><code>g</code> -&gt; go (sometimes obviously more than that)
<ul>
<li><code>gn</code> <strong>go to next (matched)</strong>, <strong>commonly used</strong></li>
<li><code>gi</code> go to (last) insert</li>
<li><code>gd</code> go to definition</li>
<li><code>gf</code> go to file</li>
</ul>
</li>
<li><code>d</code> -&gt; delete (actually puts deleted content into register); sometimes means down
<ul>
<li><code>dd</code> delete one line</li>
</ul>
</li>
<li><code>x</code> -&gt; <code>dl</code>; <code>X</code> -&gt; <code>dh</code>
<ul>
<li><code>s</code> -&gt; (<code>x</code> + <code>i</code>)</li>
<li><code>c</code> -&gt; change (<code>d</code> + <code>i</code>)</li>
</ul>
</li>
<li><code>y</code> -&gt; yank</li>
<li><code>p</code> -&gt; do paste | as paragraph</li>
<li><code>{</code> <code>}</code> -&gt; paragraph</li>
<li><code>f</code> -&gt; find occurrence (<strong>char</strong>)
<ul>
<li><code>;</code> -&gt; next occurrence</li>
<li><code>,</code> -&gt; last occurrence</li>
<li><code>t</code> -&gt; till next occurrence</li>
<li><code>F</code> -&gt; backward to occurrence</li>
</ul>
</li>
<li><code>/</code> -&gt; search item with pattern
<ul>
<li><code>n</code> -&gt; next item</li>
<li><code>?</code> -&gt; back search</li>
</ul>
</li>
<li><code>u</code> -&gt; undo; <code>Ctrl + R</code> redo</li>
<li><code>123…</code> -&gt; as line number / do multiple times</li>
<li><code>i</code> -&gt; do insert | as inner (inside); <code>o</code> -&gt; open a line below; <code>a</code> -&gt; append | around</li>
<li><code>s</code> -&gt; as sentence | do substitute</li>
<li><code>q</code> -&gt; record macro</li>
<li><code>v</code> -&gt; visual</li>
<li><code>s</code> -&gt; surrounding. <code>cs{old}{new}</code>. plugin command
<ul>
<li><code>v</code> <code>S{desire pair}</code> -&gt; surrounding by.</li>
</ul>
</li>
<li><code>J</code> join</li>
<li><code>r</code> replace</li>
</ol>
<hr>
<h4 id="special-characters">Special Characters</h4>
<ol>
<li><code>@</code> -&gt; execute register content</li>
<li><code>.</code> <strong>&gt; as current line | do repeat last change</strong>, <strong>very commonly used</strong>, for repeating <strong>edit</strong> operations</li>
<li><code>%</code> -&gt; as all lines(all contents); in normal mode represents matching symbols like <code>{[(</code></li>
<li><code>0</code> -&gt; beginning of line
<ul>
<li><code>$</code> -&gt; end of line</li>
<li><code>^</code> first meaningful character</li>
<li><code>_</code> first meaningful character (can be operated by <code>g</code> etc.)</li>
<li><code>g_</code> last meaningful character</li>
</ul>
</li>
<li><code>;</code> <strong>repeat</strong> last <code>f, F, t, T</code> command. For example, if you used <code>f</code> to find a <strong>character</strong>, pressing <code>;</code> will continue to find the next matching character.
<ul>
<li><code>,</code> reverse repeat</li>
</ul>
</li>
<li><code>'</code> for mark navigation. For example, pressing <code>'a</code> jumps to the beginning of line of mark ‘a’.</li>
<li>``` (backtick) for mark navigation. For example, pressing ``a` jumps to the exact position of mark ‘a’.</li>
<li><code>~</code> change char case.</li>
<li><code>&amp;</code> repeat last substitution command</li>
</ol>
<hr>
<h4 id="modes">Modes</h4>
<ol>
<li>Normal mode: Enter normal mode when first starting, press <code>i</code> (insert) to enter insert mode, press <code>:</code> to enter command input mode</li>
<li>Insert mode: Edit file, press Esc to exit.</li>
<li>Command input mode: Input commands, press Esc to exit.</li>
<li>Press <code>v</code> to enter visual mode, generally used for selecting paragraphs</li>
</ol>
<h4 id="command-structure">Command Structure</h4>
<ol>
<li>Normal mode commands are almost based on the <code>verb</code> + <code>adj(count)</code> + <code>obj(motion, text-object)</code> pattern, e.g.: <code>d3j</code>, <code>ca(</code>
<ul>
<li>Omitting <code>verb</code> means <strong>cursor movement</strong>, which can actually be understood as a type of <code>verb</code>.
<ul>
<li>Example: <code>3j</code>, move down 3 lines</li>
<li>Example: <code>0</code>, <code>$</code>, these are special characters</li>
<li>Example: <code>v3w</code>, <code>v</code> only switches mode, doesn’t count as <code>verb</code>, but subsequent behavior without <code>verb</code> is treated as cursor movement</li>
</ul>
</li>
<li><strong>Special case</strong>: Omitting <code>adj.</code> means based on current position, or only operating on <strong>one object</strong>.
<ul>
<li>Example: <code>cw</code>, <code>f{</code></li>
</ul>
</li>
<li><strong>Special case</strong>: Omitting both <code>adj.</code> and <code>obj.</code> generally means some single character/line shortcuts
<ul>
<li>Example: <code>dd</code>, <code>yy</code>, <code>gg</code></li>
<li>Example: <code>s</code>, <code>x</code>, <code>~</code>, <code>u</code></li>
</ul>
</li>
</ul>
</li>
<li>Command line mode has almost no pattern. If anything, they can almost all be categorized as command-like modes.
<ul>
<li>verb + obj pattern: <code>:set number</code>, <code>:r file</code> (read file)</li>
<li>adj + verb pattern: <code>:3,5 d</code>
<ul>
<li>adj + verb + obj: <code>:3,5 d0</code></li>
</ul>
</li>
<li>obj pattern: <code>:map</code></li>
<li>verb pattern: <code>:w</code>, <code>:q</code></li>
<li>Special pattern (can be viewed as mode switching): <code>:!command</code> (execute external command)</li>
<li>Command-like pattern: <code>:s/foo/bar/gc</code></li>
</ul>
</li>
</ol>
<h4 id="repeat-operations">Repeat Operations</h4>
<ul>
<li><code>.</code> for <strong>modifications</strong>.</li>
<li><code>;</code> for f, etc.</li>
<li><code>r</code> means replace</li>
<li><code>f</code> <code>sth</code> -&gt; <code>r</code> -&gt; <code>;</code> -&gt; <code>.</code> -&gt; <code>;</code> -&gt; <code>.</code> -&gt; … : guess what will happen?</li>
<li><code>gn</code> for <code>/</code> etc. Need to operate on current search content once first, then use <code>.</code> to repeat.</li>
</ul>
<h4 id="tips">Tips</h4>
<ul>
<li><code>verb</code> is almost never absent, omitting <code>verb</code> generally means <strong>movement</strong> (<code>v</code> provides selection function, but still needs to <strong>move</strong> to <strong>some position</strong> to trigger)</li>
<li>At the same time, <code>obj</code> is also almost never absent, omitting <code>obj</code> generally means <strong>current position</strong></li>
</ul>
<p>When inputting commands, if you’re unclear what else to input, consider these questions:</p>
<ol>
<li>
<p>Does the command have an object? E.g., <code>w, p, s</code>.
(Specifically, line operations generally omit objects).
Selection in <code>v</code> mode actually provides objects. Similarly, <strong>movement actions actually also provide objects.</strong>
So, this part should be <strong>considered first, but input last</strong>.</p>
</li>
<li>
<p>Does the command have modifiers?
If there’s a <strong>clear area to operate on</strong>, you must pay attention to modifier input.
Because if not provided, it will <strong>immediately</strong> operate based on current position, very easy to cause misoperations.</p>
</li>
<li>
<p>What does the command need to do?
Please treat this as the last part to think about, to control vim behavior more precisely.
But when inputting commands, generally need to input first.
So, <strong>input this first.</strong></p>
</li>
</ol>
<p><strong>Seqs: 3 → 2 → 1</strong></p>
<hr>
<h3 id="commonly-used-commands">Commonly used Commands</h3>
<ul>
<li><code>:w</code> save</li>
<li><code>:q</code> quit</li>
<li><code>:q!</code> force quit without saving</li>
<li><code>:w filename</code> save file as filename</li>
<li><code>:w! filename</code> force save to filename</li>
<li><code>:set nu</code> <code>:set number</code> display line numbers, <strong>commonly used</strong></li>
<li><code>/word</code> search downward (note, no <code>:</code>, when pressing <code>/</code>, command line becomes <code>/</code> mode)
<ul>
<li>Press <code>n, N</code> to search next/previous</li>
<li><code>?word</code> search upward</li>
</ul>
</li>
<li><code>u</code> and <code>:u</code> undo</li>
<li><code>Ctrl + R</code> redo</li>
<li><code>x</code> = <code>dl</code>, <code>X</code> = <code>dh</code></li>
<li><code>s</code> = <code>ch</code></li>
</ul>
<h4 id="compound-commands">Compound Commands</h4>
<ul>
<li><code>:5 d</code> delete line 5, <strong>commonly used</strong></li>
<li><code>:3,5 d</code> delete <strong>lines 3 to 5</strong></li>
<li><code>:$ d</code> delete last line of document</li>
<li><code>:% d</code> delete all content in document</li>
<li><code>:n move m</code> move line n to after line m, <strong>commonly used</strong></li>
<li><code>:n,n+3 t m</code> copy <strong>lines n to n+3</strong> to <strong>after</strong> line m, <strong>commonly used</strong>
<ul>
<li>Summary: <code>:n,m</code> generally means from line n to line m</li>
</ul>
</li>
<li><code>:%s/hello/nihao/g</code> replace all hello with nihao, similar to <code>sed</code> operation
<ul>
<li><code>:s/hello/nihao/g</code> only replace in current line</li>
</ul>
</li>
<li><code>:5,8s/hello/nihao/g</code> replace hello with nihao in lines 5-8</li>
</ul>
<h3 id="common-shortcuts">Common Shortcuts</h3>
<h4 id="movement">Movement</h4>
<ol>
<li><code>Ctrl + O</code> previous position, <code>Ctrl + I</code> next position</li>
<li>If you have <code>Home</code> <code>End</code> <code>PageUp</code> and <code>PageDown</code> keys, you can use them directly, adding <code>Ctrl</code> is more convenient
<ol>
<li><code>PgUp</code> <code>PgDown</code> behavior varies, specifically use with <code>Ctrl</code> and <code>Shift</code></li>
</ol>
</li>
<li><code>Ctrl + U</code> and <code>Ctrl + D</code> half screen scroll; <code>Ctrl + F</code> and <code>Ctrl + B</code> full screen scroll</li>
<li><code>Ctrl + Up</code> to beginning of line, vice versa</li>
</ol>
<hr>
<h3 id="normal-mode">Normal Mode</h3>
<h4 id="cursor-movement"><strong>Cursor Movement</strong></h4>
<h4 id="character-based-movement">Character-based Movement</h4>
<ul>
<li><code>h</code> <code>l</code> move left/right, <code>k</code> <code>j</code> move up/down, arrow keys also work</li>
<li>Use <code>f</code> to find next <strong>character</strong>, uppercase for reverse search; using <code>t</code> stops before that character
<ul>
<li>Use <code>;</code> and <code>,</code> to repeat forward/backward search</li>
</ul>
</li>
<li><code>^</code> move to first non-whitespace position</li>
<li><code>g_</code> find first non-whitespace position from end of line</li>
<li>Use <code>$</code> to move to end of line</li>
<li>Use <code>%</code> to match brackets like <code>( { [</code></li>
</ul>
<h4 id="word-based-movement">Word-based Movement</h4>
<ul>
<li><code>w</code> move to next word, <strong>commonly used</strong>, remember as word</li>
<li><code>b</code> move to beginning of current/previous word, <strong>commonly used</strong>, remember as back</li>
<li><code>e</code> move to end of current/next word, <strong>commonly used</strong>, remember as end
<ul>
<li>Uppercase <code>W, B, E, gE</code> for including characters after words</li>
<li><code>ge</code> move to end of previous word</li>
<li><code>3w</code> can move 3 times</li>
</ul>
</li>
<li>Use <code>/</code> and <code>?</code> to search for <code>pattern</code>, use <code>n</code> and <code>N</code> to jump to next/previous</li>
</ul>
<h4 id="line-based-movement">Line-based Movement</h4>
<ul>
<li><code>g</code> is the most basic line movement command</li>
<li><code>0</code> move cursor to beginning of line, <code>$</code> move cursor to end of line</li>
<li><code>Home</code> key to beginning of line, <code>End</code> key to end of line</li>
<li><code>G</code> (Shift+G)/<code>gg</code> move cursor to end/beginning of file</li>
<li>Actually <code>G</code> is go, so you can input <code>500G</code> or <code>500gg</code> to locate to line <code>500</code>, <strong>commonly used</strong>
<ul>
<li>Or directly use <code>:line_number</code> to locate</li>
<li><code>gi</code> return to last insert location, <strong>commonly used</strong></li>
</ul>
</li>
</ul>
<h4 id="block-or-screen-based-movement">Block or Screen-based Movement</h4>
<ul>
<li><code>{</code> <code>}</code> move by paragraph</li>
<li><code>H</code> move to <strong>top line of screen</strong>; <code>L</code> move to <strong>bottom line of screen</strong>; <code>M</code> move to <strong>middle of screen</strong></li>
</ul>
<h4 id="mark-based-movement">Mark-based Movement</h4>
<ul>
<li><code>ma</code> set mark a</li>
<li><code>'a</code> jump to beginning of line of mark a</li>
<li>``a` jump to exact position of mark a</li>
<li><code>''</code> jump to beginning of line of previous position, <strong>commonly used</strong></li>
<li>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"></code></pre></div></li>
</ul>
<hr>
<h4 id="operation-commands">Operation Commands</h4>
<p>Follow <code>{operator}{count}{motion}</code> pattern, e.g.: <code>d2w</code></p>
<ul>
<li><code>c</code> change, <code>d</code> delete, <code>y</code> yank (copy), <code>p</code> paste
<ul>
<li>change means delete corresponding content and directly enter insert mode</li>
</ul>
</li>
<li><code>gu</code> <code>gU</code> or directly press <code>~</code> to change char’s case (<strong>commonly used</strong>)</li>
<li><code>=</code> format, for formatting, need to set code standards in advance, e.g.:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">set autoindent        &#34; Inherit indentation from previous line
</span></span><span class="line"><span class="cl">set smartindent       &#34; Smart indentation based on syntax
</span></span><span class="line"><span class="cl">set cindent           &#34; C/C++ style indentation
</span></span><span class="line"><span class="cl">set shiftwidth=4      &#34; Move 4 spaces for each indentation operation
</span></span><span class="line"><span class="cl">set tabstop=4         &#34; Display one Tab as 4 spaces
</span></span><span class="line"><span class="cl">set expandtab         &#34; Use spaces instead of Tab
</span></span></code></pre></div><p>Common formatting commands:</p>
<ul>
<li>
<p><code>==</code>: Format current line.</p>
</li>
<li>
<p><code>=motion</code>: Format range specified by <code>motion</code>.</p>
</li>
<li>
<p><code>=ap</code>: Format current paragraph (<code>ap</code> means “a paragraph”).</p>
</li>
<li>
<p><code>=%</code>: Format content within brackets matching current cursor position.</p>
</li>
<li>
<p><code>gg=G</code>: Format entire file.</p>
</li>
<li>
<p>Use <code>&gt;&gt;</code> for indentation, use <code>&gt;</code> when target is provided</p>
</li>
</ul>
<h4 id="text-objects-delete-content-of-specific-patterns">Text Objects (delete content of specific patterns)</h4>
<p>Follow <code>{operator}{a/i}{text object}</code> pattern, e.g.: <code>di'</code> (delete inside ’)</p>
<ul>
<li>Generally used with <code>c</code>, <code>d</code></li>
<li>a -&gt; around, i -&gt; inside</li>
<li>text-object identifiers:
<ul>
<li><code>w</code> word</li>
<li><code>s</code> sentence</li>
<li><code>p</code> paragraph</li>
<li><code>'&quot;[{&lt;</code> ` corresponding to respective special blocks</li>
<li><code>t</code> tag, commonly used in html language, between <code>&gt;&lt;</code></li>
</ul>
</li>
</ul>
<h4 id="copy-and-delete">Copy and Delete</h4>
<ul>
<li><code>yy</code> copy current line, <strong>commonly used</strong></li>
<li><code>dd</code> cut current line, <strong>commonly used</strong></li>
<li><code>3dd</code> delete 3 lines, <strong>commonly used</strong></li>
<li><code>p</code>/<code>P</code> paste content after/before cursor, <strong>commonly used</strong></li>
<li><code>x</code> delete character at cursor, <code>X</code> delete previous character</li>
<li><code>r</code> modify character at cursor</li>
<li><code>R</code> enter replace mode</li>
</ul>
<h4 id="undo">Undo</h4>
<ul>
<li><code>u</code> undo, <strong>commonly used</strong></li>
<li><code>Ctrl + R</code> redo, <strong>commonly used</strong></li>
</ul>
<h4 id="enter-insert-mode">Enter Insert Mode</h4>
<ul>
<li><code>i</code> enter insert mode at current position</li>
<li><code>a</code> enter insert mode at next character</li>
<li><code>A</code> enter insert mode at end of line</li>
<li><strong><code>o</code> enter insert mode on next line</strong>, often used with <code>G</code> and <code>End</code>, <strong>commonly used</strong></li>
<li><code>s</code> delete current character and enter insert mode</li>
<li><code>S</code> delete current line and enter insert mode</li>
<li><code>cw</code> delete next word and enter insert mode</li>
<li><code>cb</code> delete previous word and enter insert mode</li>
</ul>
<hr>
<h3 id="insert-mode">Insert Mode</h3>
<p>Generally use shortcuts for operations</p>
<h4 id="cursor-movement-1">Cursor Movement</h4>
<ol>
<li><code>Ctrl + A</code> move cursor to beginning of line, uppercase moves to beginning of document</li>
<li><code>Ctrl + E</code> move cursor to end of line</li>
</ol>
<h4 id="text-operations">Text Operations</h4>
<ol>
<li><code>Ctrl + W</code>: Delete one word before cursor.</li>
<li><code>Ctrl + U</code>: Delete all content from current cursor position to beginning of line.</li>
<li><code>Ctrl + T</code> increase indentation to the right</li>
<li><code>Ctrl + D</code> decrease indentation to the left</li>
<li><code>Ctrl + R</code>: Insert register content. After pressing, need to input register identifier, e.g., <code>Ctrl + R, 0</code> inserts content of register 0.</li>
</ol>
<h4 id="completion-features">Completion Features</h4>
<ol>
<li><code>Ctrl + N</code>: Auto-complete next matching word. <strong>commonly used</strong></li>
<li><code>Ctrl + P</code>: Auto-complete previous matching word.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + L</code>: Full line completion, shows dropdown menu</li>
<li><code>Ctrl + X</code>, <code>Ctrl + N/P</code>: Word completion based on current file.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + F</code>: Filename completion.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + K</code>: Dictionary lookup completion.</li>
</ol>
<h4 id="others">Others</h4>
<ol>
<li><code>Ctrl + C</code>: Exit input mode. Replace Esc, <strong>commonly used</strong></li>
<li><code>Ctrl + O</code>: Temporarily switch to normal mode to execute one command, then return to input mode. <strong>commonly used</strong></li>
<li>What if you press wrong key? In normal mode use <code>Ctrl + O</code> to return to previous position, meaning in input mode press <code>Ctrl + O</code> x2</li>
</ol>
<hr>
<h3 id="visual-mode">Visual Mode</h3>
<p>Follow <code>{trigger v}{motion}{operator}</code> pattern, e.g.: <code>v2wd</code> (select two words then delete)</p>
<ul>
<li>Press <code>v</code> for character selection, <code>V</code> for line selection, <code>Ctrl + V</code> for block selection</li>
<li>Generally only used for copy-paste, operation speed is slow</li>
</ul>
<hr>
<h3 id="-command-mode"><code>:</code> Command Mode</h3>
<h4 id="batch-processing-delete-move-copy-paste">Batch Processing (delete, move, copy, paste)</h4>
<ol>
<li><code>:2,5d a</code>: Delete <strong>lines 2 to 5</strong> and <strong>save in register a</strong></li>
<li><code>0</code> line 0; `# Vim in a Nutshell</li>
<li><code>:.,+3d</code> delete current lint &amp; plus 3 lines</li>
<li>In <code>visual</code> mode，<code>:'&lt;,'&gt;d</code> means “delete selected content”</li>
<li><code>@:</code> repeat last <code>:</code> command
<ul>
<li>After using <code>q</code> for macro recording we can use <code>@@</code> repeat it</li>
<li>After <code>@:</code> , <code>@@</code> is still available</li>
</ul>
</li>
<li><code>:'&lt;,'&gt;move .</code>
<ul>
<li><code>:m 10</code> move (current line) to 10 line after</li>
</ul>
</li>
<li><code>:/</code> looking for last found pattern</li>
</ol>
<hr>
<h4 id="quick-reference-1">Quick Reference</h4>
<h4 id="find-and-replace">Find and Replace</h4>
<ul>
<li><strong><code>:%s/old/new/g</code></strong>: In entire file range, replace all strings matching <code>old</code> with <code>new</code>. Add <code>c</code> to ask before each replacement.</li>
<li><strong><code>:s/old/new/g</code></strong>: Replace all <code>old</code> with <code>new</code> in current line.</li>
<li><strong><code>:g/pattern/d</code></strong>: Delete all lines matching <code>pattern</code>.</li>
<li><strong><code>:'&lt;,'&gt;s/old/new/g</code></strong>: In visual mode selected range, replace all <code>old</code> with <code>new</code>.</li>
<li><strong><code>:'&lt;,'&gt;normal command</code></strong>: Execute <code>normal</code> mode command on each line selected in visual mode.</li>
</ul>
<h4 id="line-operations">Line Operations</h4>
<ul>
<li><strong><code>:d</code></strong>: Delete current line (similar to <code>dd</code>).</li>
<li><strong><code>:t .+1</code></strong>: Copy current line and paste to next line.</li>
<li><strong><code>:m .+1</code></strong>: Move current line down one line.</li>
<li><strong><code>:m .-2</code></strong>: Move current line up two lines.</li>
<li><code>:-3,. m .+1</code>: Move 3 lines above current line to below current line</li>
<li><code>:-3,.y | :.+1put</code>: Copy above three lines, paste to next line. <code>put</code> creates new line, <code>p</code> pastes at cursor position</li>
</ul>
<h4 id="sed-like-command-usage">sed-like Command Usage</h4>
<ol>
<li>Replace all matching patterns at once: <code>:%s/pattern/replacement/gc</code> for entire file range (<code>%</code>), substitute (<code>s</code>) <code>pattern</code> with <code>replacement</code></li>
<li><code>gc</code> are <code>flags</code>, common <code>flags</code> include:
<ul>
<li><code>g</code>: Global replacement (apply command to all lines)</li>
<li><code>c</code>: Ask before each command execution.</li>
<li><code>i</code>: Ignore case</li>
<li><code>n</code>: Maximum number of replacements</li>
<li><code>p</code>: Print results</li>
<li><code>v</code>: Invert results</li>
<li><code>!</code>: Pass to external tool -&gt; <code>%!sort</code> will sort entire text</li>
</ul>
</li>
<li><strong>Explicitly</strong> use <strong>normal commands</strong> in <code>Ex</code> mode. Use <code>norm</code>
<ul>
<li>Very useful with v mode</li>
<li>Example: <code>:'&lt;,'&gt;norm A!</code>, will <strong>for content selected in v mode (‘&lt;,’&gt;)</strong>, uniformly <strong>add a “!” at the end of lines (A)</strong></li>
</ul>
</li>
</ol>
<p><code>%</code> itself is shorthand for **`1,# Vim in a Nutshell</p>
<hr>
<h3 id="tips-1">Tips</h3>
<ul>
<li>Accidentally pressed <code>Ctrl + S</code>? Use <code>Ctrl + Q</code> to release</li>
<li>It’s best not to use the right numeric keypad for editing, there might be key conflicts</li>
</ul>
<hr>
<h3 id="copy-paste-issues">Copy-Paste Issues</h3>
<p>Vim editor has its own clipboard system called registers. Vim uses registers to store text, which are different from X11 clipboards. If Vim is compiled with X11 clipboard support (through +clipboard option), then you can use special registers <code>&quot;*</code> and <code>&quot;+</code> to access X11’s PRIMARY and CLIPBOARD.</p>
<h4 id="paste-mode">Paste Mode</h4>
<p>To prevent auto-formatting from corrupting pasted content, Vim provides paste mode. Before pasting, execute <code>:set paste</code> command to enter paste mode, which will temporarily disable auto-indent, auto-wrap and other functions. After pasting, execute <code>:set nopaste</code> to return to normal mode.</p>
<p>You can also install some programs to access X11 clipboard, such as <strong>xclip</strong> or <strong>xsel</strong>.</p>
<p>Right mouse button enters visual mode?</p>
<ul>
<li><code>:set mouse-=a</code></li>
</ul>
<hr>
<h4 id="register-overview">Register Overview</h4>
<p>Vim uses a set of registers as its “clipboard”. These registers can be used to save text and paste later. Each register has an identifier, which can be a single letter or special character. Here are some basics about Vim registers:</p>
<p>Note, to use registers, first press <code>&quot;</code>, then <strong>switch</strong> to the desired register, then perform operations</p>
<p>To view register status, type <code>:reg</code> in command line mode</p>
<hr>
<h4 id="basic-registers">Basic Registers</h4>
<ul>
<li><code>&quot;&quot;</code> - Default register, if you don’t know where copied content went, look here</li>
<li><code>&quot;0</code> - Number 0 register. Stores content of your last yank (copy).</li>
<li><code>&quot;-</code> - Small delete register. Stores content of your last delete or change that’s less than one line.</li>
<li><code>&quot;1</code> to <code>&quot;9</code> - Number registers. Store your recent delete or change history (<code>&quot;1</code> is most recent, <code>&quot;9</code> is oldest).</li>
<li><code>&quot;a</code> to <code>&quot;z</code> or <code>&quot;A</code> to <code>&quot;Z</code> - Named registers. You can use lowercase letters to store text, uppercase letters to append text to corresponding lowercase register.</li>
</ul>
<hr>
<h4 id="special-registers">Special Registers</h4>
<ul>
<li><code>&quot;*</code> and <code>&quot;+</code> - Clipboard registers. In Vim with clipboard support (usually GUI version Vim or Vim with <code>+clipboard</code> feature), these two registers communicate with system clipboard:
<ul>
<li><code>&quot;*</code> register corresponds to X11’s <code>PRIMARY</code> clipboard (usually the select-to-copy one).</li>
<li><code>&quot;+</code> register corresponds to <code>CLIPBOARD</code> clipboard (usually used with <code>Ctrl+C</code>/<code>Ctrl+V</code> key combinations). <strong>Most commonly used.</strong></li>
</ul>
</li>
</ul>
<hr>
<h4 id="using-registers">Using Registers</h4>
<ul>
<li><strong>Copy to register</strong>: You can use <code>&quot;ay</code> to copy to register <code>a</code>, where <code>a</code> is the register name, <code>y</code> is the yank command.
<ul>
<li>Almost the same in visual mode</li>
</ul>
</li>
<li><strong>Paste from register</strong>: To paste from register, you can use <code>&quot;ap</code> to paste content of register <code>a</code>, where <code>a</code> is the register name, <code>p</code> is the paste command.</li>
<li><strong>In insert mode</strong>: Use <code>Ctrl + R</code> to call up <code>&quot;</code> symbol</li>
</ul>
<h4 id="using-registers-in-insert-mode">Using Registers in Insert Mode</h4>
<p>Press</p>
<p><code>Ctrl + R + register name</code></p>
<p>For example</p>
<p><code>Ctrl + R + &quot;</code> uses default register, <code>Ctrl + R + +</code> uses system register.</p>
<hr>
<h4 id="using-registers-in-terminal">Using Registers in Terminal</h4>
<p>When you use Vim in terminal instead of GUI version, accessing system clipboard becomes more complex, because Vim needs to include clipboard support at compile time. You can run <code>vim --version</code> to see if your Vim supports clipboard (look for <code>+clipboard</code> or <code>+xterm_clipboard</code>).</p>
<p>If your Vim supports clipboard, you can interact with system clipboard in the following ways:</p>
<ul>
<li>Use <code>&quot;*y</code> to copy to system’s PRIMARY clipboard.</li>
<li>Use <code>&quot;+y</code> to copy to system’s CLIPBOARD clipboard.</li>
<li>Use <code>&quot;*p</code> or <code>&quot;+p</code> to paste from corresponding system clipboard to Vim.</li>
</ul>
<p>If your Vim doesn’t have clipboard support, you won’t be able to directly access system clipboard from Vim. In this case, you need to use external programs (like <code>xclip</code> or <code>xsel</code>) to help you copy Vim register content to system clipboard, or paste from system clipboard to Vim.</p>
<hr>
<h3 id="external-commands">External Commands</h3>
<h4 id="using--to-execute-external-commands">Using <code>:!</code> to Execute External Commands</h4>
<p>You can use <code>:!</code> followed by command to execute any external command. For example, if you want to see current directory contents, you can type in Vim’s command mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:!ls
</span></span></code></pre></div><h4 id="using-r-to-read-external-command-output">Using <code>:r</code> to Read External Command Output</h4>
<p>If you want to insert output of <code>sed</code>, <code>awk</code> or other commands into current Vim editor text, you can use <code>:r !</code> command. For example, if you want to insert <code>ls</code> command output at current position, you can type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:r !ls
</span></span></code></pre></div><h4 id="using--to-process-entire-file-content-through-external-command">Using <code>:%!</code> to Process Entire File Content Through External Command</h4>
<p>If you want to apply <code>sed</code> or <code>awk</code> command to entire file content and replace current file content, you can use <code>:%!</code> followed by corresponding command. For example, use <code>sed</code> command to replace all “foo” with “bar” in document:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:%!sed <span class="s1">&#39;s/foo/bar/g&#39;</span>
</span></span></code></pre></div><h4 id="partial-usage">Partial Usage</h4>
<p>You can also specify a range to use external command only on certain parts of the file. For example, only process lines 5 to 10 through <code>awk</code> command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:5,10!awk <span class="s1">&#39;{print $1}&#39;</span>
</span></span></code></pre></div><hr>
<h3 id="macro-recording"><strong>Macro Recording</strong></h3>
<ol>
<li>Use <code>q</code> for macro recording in normal mode
<ul>
<li>Give register a name, say <code>a</code>, the full name of this register is <code>@a</code></li>
<li>Press <code>q</code> again to end recording after recording is complete</li>
<li>Type <code>@a</code> to execute macro, <code>@@</code> to execute last macro, <code>9@a</code> to execute macro 9 times</li>
</ul>
</li>
<li><strong>+1 operation</strong> on numbers. <code>&lt;C-a&gt;</code>, can be used with macro recording to write ordered lists:
<ul>
<li><code>1. sth</code>, then <code>yyp</code>, perform <code>&lt;C-a&gt;</code> on 1, repeat</li>
</ul>
</li>
</ol>
<hr>
<h3 id="other-features">Other Features</h3>
<ol>
<li><strong>Spell check</strong>. <code>:set spell! spelllang=en_us</code></li>
<li><code>:set rnu</code> set <strong>relative line numbers</strong>. Convenient for jumping</li>
</ol>
]]></content:encoded></item><item><title>Golang in short</title><link>https://www.parkerchenca.com/tech/golang-in-short/</link><pubDate>Thu, 10 Sep 2026 11:24:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/golang-in-short/</guid><description>Quick notes of GO</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
No need for digging a big hole, just use it.</p>
</blockquote>
<h2 id="golang-in-short">Golang in short</h2>
<hr>
<h3 id="go-is">Go is</h3>
<ol>
<li>A modern high-level programming language that resembles C</li>
<li>Open-source, compiled, statically typed, and memory-safe</li>
</ol>
<h3 id="go-has">Go has</h3>
<ol>
<li>Simple yet powerful package management (pulls directly from GitHub)</li>
<li>Built-in concurrency primitives</li>
<li>Garbage collection (GC)</li>
<li>Lightning-fast compilation</li>
<li>Minimal syntax</li>
<li>Cross-platform compilation</li>
</ol>
<h3 id="go-doesnt-have">Go doesn&rsquo;t have</h3>
<ol>
<li>Classes and inheritance</li>
<li>Function overloading</li>
<li>Implicit type conversions</li>
</ol>
<h3 id="i-use-go-to">I use Go to</h3>
<ol>
<li>Say goodbye to Java&rsquo;s verbose syntax</li>
<li>Build web services and microservices</li>
<li>Handle high-concurrency scenarios</li>
</ol>
<h3 id="go-is-perfect-for">Go is perfect for</h3>
<ol>
<li>Web services and RESTful APIs</li>
<li>Microservices architecture</li>
<li>Network programming and distributed systems</li>
</ol>
<h3 id="go-might-not-be-ideal-for">Go might not be ideal for</h3>
<ol>
<li>GUI desktop applications</li>
<li>Kernel development</li>
<li>Machine learning (Python has a stronger ecosystem)</li>
</ol>
<hr>
<h2 id="installing-go">Installing Go</h2>
<ol>
<li>Using OS package managers
<ul>
<li>Linux: <code>apt</code>, <code>yum</code>, <code>snap</code></li>
<li>macOS: <code>brew</code></li>
<li>Windows: <code>choco</code>, <code>scoop</code>, etc.</li>
</ul>
</li>
<li>Download official precompiled binaries
<ul>
<li>Already compiled, ready to use</li>
<li>Set up path and links manually</li>
</ul>
</li>
<li>Verify with <code>go version</code></li>
</ol>
<h3 id="hello-world">Hello World</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// This is a comment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="cm">/* This is
</span></span></span><span class="line"><span class="cl"><span class="cm">   a multiline
</span></span></span><span class="line"><span class="cl"><span class="cm">   comment */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w"> </span><span class="c1">// This is the main package</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No semicolons at line endings</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;fmt&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;math&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w"> </span><span class="c1">// Importing other packages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="nx">myConstant</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="c1">// Constants need explicit initialization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;helloworld&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Package names -&gt; lowercase</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Lowercase in package -&gt; myConstant -&gt; package-private</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Capitalized -&gt; Println() -&gt; exported (public)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="types">Types</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kt">bool</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">int</span><span class="w">  </span><span class="kt">int8</span><span class="w">  </span><span class="kt">int16</span><span class="w">  </span><span class="kt">int32</span><span class="w">  </span><span class="kt">int64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">uint</span><span class="w"> </span><span class="kt">uint8</span><span class="w"> </span><span class="kt">uint16</span><span class="w"> </span><span class="kt">uint32</span><span class="w"> </span><span class="kt">uint64</span><span class="w"> </span><span class="kt">uintptr</span><span class="w"> </span><span class="c1">// Has pointers but no pointer arithmetic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">byte</span><span class="w"> </span><span class="c1">// alias for uint8</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">rune</span><span class="w"> </span><span class="c1">// alias for int32</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">     </span><span class="c1">// Represents a Unicode code point</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">     </span><span class="c1">// From ancient Nordic &#34;rune&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">float32</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">complex64</span><span class="w"> </span><span class="kt">complex128</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Zero value for reference types is nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type assertion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="p">,</span><span class="w"> </span><span class="nx">ok</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">variable</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// Returns two values, ok indicates success</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="c1">// Panics if ok is not captured and type is wrong</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">myInt</span><span class="w"> </span><span class="kt">int32</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">myAnotherInt</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">int64</span><span class="p">(</span><span class="nx">myInt</span><span class="p">)</span><span class="w"> </span><span class="c1">// Type conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// No direct conversion between bool and int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// Generally, single characters and numbers can convert</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// Otherwise, only conversions within same type family</span><span class="w">
</span></span></span></code></pre></div><h3 id="variables-and-functions">Variables and Functions</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">hi</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c1">// Variables outside functions must have explicit types</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">myFunc</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">innerHi</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;hi&#34;</span><span class="w"> </span><span class="c1">// Inside functions, use := for type inference</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">const</span><span class="w"> </span><span class="nx">hiConst</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;hi again&#34;</span><span class="w"> </span><span class="c1">// Constants cannot use :=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nx">MapFilter</span><span class="p">[</span><span class="nx">T</span><span class="w"> </span><span class="kt">any</span><span class="p">,</span><span class="w"> </span><span class="nx">R</span><span class="w"> </span><span class="nx">comparable</span><span class="p">](</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">slice</span><span class="w"> </span><span class="p">[]</span><span class="nx">T</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">mapper</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">T</span><span class="p">)</span><span class="w"> </span><span class="nx">R</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">predicate</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">R</span><span class="p">)</span><span class="w"> </span><span class="kt">bool</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">options</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nx">filtered</span><span class="w"> </span><span class="p">[]</span><span class="nx">R</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Returns a function</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">options</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nx">filtered</span><span class="w"> </span><span class="p">[]</span><span class="nx">R</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c1">// Implementation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// A complete function signature example</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Note the second func starts parameters</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// The last func starts return type -&gt; returns a function</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// T is generic, R is constraint, but they&#39;re essentially the same thing</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="p">(</span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1">// Anonymous function definition</span><span class="w">
</span></span></span></code></pre></div><h3 id="arrays-slices-and-maps">Arrays, Slices, and Maps</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Arrays - fixed length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">arr</span><span class="w"> </span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="c1">// Compiler infers length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Slices - dynamic length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">slice</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">     </span><span class="c1">// Length 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="c1">// Length 5, capacity 10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Maps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&#34;one&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;two&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m2</span><span class="p">[</span><span class="s">&#34;key&#34;</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check if key exists</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">exists</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">[</span><span class="s">&#34;key&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">exists</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="control-flow">Control Flow</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Only for loops exist</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// All parts of for loop are optional</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Loop body</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Infinite loop</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Equivalent to while(true)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Condition loop</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="o">++</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">expression</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Iterate over iterables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Similar to Python&#39;s for..in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Directly provides index and value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// No enumerate function needed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Use _, v to ignore index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// if statement</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// Can assign in condition</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Condition body</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// switch statement</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">switch</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// x is optional</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="mi">1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;one&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">:</span><span class="w">      </span><span class="c1">// Multiple values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;two, three or four&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;other&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type switch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">switch</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">x</span><span class="p">.(</span><span class="kd">type</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="kt">int</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;int: %d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="kt">string</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;string: %s\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;unknown type\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="defer-and-channels">Defer and Channels</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// defer - deferred execution (stack structure, LIFO)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">panic</span><span class="p">(</span><span class="s">&#34;!&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Output order: 3 2 1 panic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// defer provides stack-based deferred execution</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// panic triggers deferred functions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// channel - channels (queue structure, FIFO)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">channelExample</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="c1">// Buffer size 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="c1">// 10 goes in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="c1">// then 20 goes in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">took</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">myChan</span><span class="w">      </span><span class="c1">// took is 10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">&lt;-</span><span class="nx">myChan</span><span class="p">)</span><span class="w"> </span><span class="c1">// 20</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">blockingChannel</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">ch</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// Unbuffered channel</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ch &lt;- 1           // Will block! Need another goroutine to receive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Correct approach</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">&lt;-</span><span class="nx">ch</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Channels provide a queue-like or pipe-like structure</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// FIFO</span><span class="w">
</span></span></span></code></pre></div><h3 id="pointers">Pointers</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Go has pointers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Useful when referencing large data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Go&#39;s design philosophy is very close to C-family languages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Fun fact: When passing pointers to functions, both C and Go copy the pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// All parameters are pass-by-value in both languages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// But C++ has completely different reference passing mechanism</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">var</span><span class="w"> </span><span class="nx">myPtr</span><span class="w"> </span><span class="o">*</span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// var anotherPtr uintptr  // uintptr is integer type, not pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myPtr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">i</span><span class="w"> </span><span class="c1">// Take address</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">*</span><span class="nx">myPtr</span><span class="p">)</span><span class="w"> </span><span class="c1">// Dereference, outputs 42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">*</span><span class="nx">myPtr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">43</span><span class="w">         </span><span class="c1">// Modify through pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w">      </span><span class="c1">// Outputs 43</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// No pointer arithmetic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="format-verbs">Format Verbs</h3>
<table>
	<thead>
			<tr>
					<th>Verb</th>
					<th>Description</th>
					<th>Example</th>
					<th>Output</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>%v (value)</td>
					<td>Default format</td>
					<td>Printf(&quot;%v&quot;, people)</td>
					<td>{zhangsan}</td>
			</tr>
			<tr>
					<td>%+v</td>
					<td>Adds field names for structs</td>
					<td>Printf(&quot;%+v&quot;, people)</td>
					<td>{Name:zhangsan}</td>
			</tr>
			<tr>
					<td>%#v</td>
					<td>Go syntax representation</td>
					<td>Printf(&quot;%#v&quot;, people)</td>
					<td>main.Human{Name:&ldquo;zhangsan&rdquo;}</td>
			</tr>
			<tr>
					<td>%T (type)</td>
					<td>Type in Go syntax</td>
					<td>Printf(&quot;%T&quot;, people)</td>
					<td>main.Human</td>
			</tr>
			<tr>
					<td>%%</td>
					<td>Percent sign</td>
					<td>Printf(&quot;%%&quot;)</td>
					<td>%</td>
			</tr>
			<tr>
					<td>%t (true)</td>
					<td>true or false</td>
					<td>Printf(&quot;%t&quot;, true)</td>
					<td>true</td>
			</tr>
			<tr>
					<td>%b (binary)</td>
					<td>Binary representation</td>
					<td>Printf(&quot;%b&quot;, 5)</td>
					<td>101</td>
			</tr>
			<tr>
					<td>%c (char)</td>
					<td>Unicode character</td>
					<td>Printf(&quot;%c&quot;, 0x4E2D)</td>
					<td>中</td>
			</tr>
			<tr>
					<td>%d (decimal)</td>
					<td>Decimal</td>
					<td>Printf(&quot;%d&quot;, 0x12)</td>
					<td>18</td>
			</tr>
			<tr>
					<td>%o (octal)</td>
					<td>Octal</td>
					<td>Printf(&quot;%o&quot;, 10)</td>
					<td>12</td>
			</tr>
			<tr>
					<td>%q (quote)</td>
					<td>Single-quoted character literal</td>
					<td>Printf(&quot;%q&quot;, 0x4E2D)</td>
					<td>&lsquo;中&rsquo;</td>
			</tr>
			<tr>
					<td>%x</td>
					<td>Hexadecimal, lowercase</td>
					<td>Printf(&quot;%x&quot;, 13)</td>
					<td>d</td>
			</tr>
			<tr>
					<td>%X</td>
					<td>Hexadecimal, uppercase</td>
					<td>Printf(&quot;%X&quot;, 13)</td>
					<td>D</td>
			</tr>
			<tr>
					<td>%U (unicode)</td>
					<td>Unicode format: U+1234</td>
					<td>Printf(&quot;%U&quot;, 0x4E2D)</td>
					<td>U+4E2D</td>
			</tr>
			<tr>
					<td>%b</td>
					<td>Binary exponent scientific notation</td>
					<td>Printf(&quot;%b&quot;, 10.5)</td>
					<td>5835037194198p-49</td>
			</tr>
			<tr>
					<td>%e</td>
					<td>Scientific notation</td>
					<td>Printf(&quot;%e&quot;, 10.2)</td>
					<td>1.020000e+01</td>
			</tr>
			<tr>
					<td>%E</td>
					<td>Scientific notation</td>
					<td>Printf(&quot;%E&quot;, 10.2)</td>
					<td>1.020000E+01</td>
			</tr>
			<tr>
					<td>%f (float)</td>
					<td>Decimal point, no exponent</td>
					<td>Printf(&quot;%f&quot;, 10.2)</td>
					<td>10.200000</td>
			</tr>
			<tr>
					<td>%g</td>
					<td>Compact format (%e or %f)</td>
					<td>Printf(&quot;%g&quot;, 10.20)</td>
					<td>10.2</td>
			</tr>
			<tr>
					<td>%G</td>
					<td>Compact format (%E or %f)</td>
					<td>Printf(&quot;%G&quot;, 10.20)</td>
					<td>10.2</td>
			</tr>
			<tr>
					<td>%s (string)</td>
					<td>String (string or []byte)</td>
					<td>Printf(&quot;%s&quot;, []byte(&ldquo;Go&rdquo;))</td>
					<td>Go</td>
			</tr>
			<tr>
					<td>%q</td>
					<td>Double-quoted string</td>
					<td>Printf(&quot;%q&quot;, &ldquo;Go&rdquo;)</td>
					<td>&ldquo;Go&rdquo;</td>
			</tr>
			<tr>
					<td>%x</td>
					<td>Hex, lowercase, two chars per byte</td>
					<td>Printf(&quot;%x&quot;, &ldquo;golang&rdquo;)</td>
					<td>676f6c616e67</td>
			</tr>
			<tr>
					<td>%X</td>
					<td>Hex, uppercase, two chars per byte</td>
					<td>Printf(&quot;%X&quot;, &ldquo;golang&rdquo;)</td>
					<td>676F6C616E67</td>
			</tr>
			<tr>
					<td>%p (pointer)</td>
					<td>Hexadecimal with 0x prefix</td>
					<td>Printf(&quot;%p&quot;, &amp;people)</td>
					<td>0x4f57f0</td>
			</tr>
			<tr>
					<td>+</td>
					<td>Always print sign; ASCII-only for %+q</td>
					<td>Printf(&quot;%+q&quot;, &ldquo;中文&rdquo;)</td>
					<td>&ldquo;\u4e2d\u6587&rdquo;</td>
			</tr>
			<tr>
					<td>-</td>
					<td>Pad with spaces on right (left-align)</td>
					<td></td>
					<td></td>
			</tr>
			<tr>
					<td>#</td>
					<td>Alternate format: 0 prefix for octal (%#o), 0x for hex (%#x), etc.</td>
					<td>Printf(&quot;%#U&quot;, &lsquo;中&rsquo;)</td>
					<td>U+4E2D &lsquo;中&rsquo;</td>
			</tr>
			<tr>
					<td>&rsquo; '</td>
					<td>Space for elided sign; spaces between bytes for hex</td>
					<td></td>
					<td></td>
			</tr>
			<tr>
					<td>0</td>
					<td>Pad with zeros; moves padding after sign for numbers</td>
					<td></td>
					<td></td>
			</tr>
	</tbody>
</table>
<p>Reference:</p>
<h3 id="string-formatting">String Formatting</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// %[flags][width][.precision]verb</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Width and alignment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34;   42&#34; right-aligned, width 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;42   &#34; left-aligned, width 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%05d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;00042&#34; zero-padded</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// String alignment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;|     hello|&#34; right-aligned</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%-10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;|hello     |&#34; left-aligned</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;|        你好|&#34; handles Chinese</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">pi</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mf">3.14159265359</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Decimal precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.14&#34; 2 decimal places</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.4f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.1416&#34; 4 decimal places (rounded)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%8.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">    </span><span class="c1">// &#34;    3.14&#34; width 8, 2 decimals</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%08.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;00003.14&#34; zero-padded</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Scientific notation precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.3e\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.142e+00&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.3g\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">0.00012345</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;0.000123&#34; auto format</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// + flag: show sign</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%+d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34;+42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%+f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">3.14</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;-3.140000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// # flag: show base prefix</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#x\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">255</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;0xff&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#o\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">8</span><span class="p">)</span><span class="w">       </span><span class="c1">// &#34;010&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#b\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">       </span><span class="c1">// &#34;0b101&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Space: add space for positive numbers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;% d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34; 42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;% d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;-42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Making tables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-10s %8.2f %5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Apple&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">3.99</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-10s %8.2f %5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Banana&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">12.5</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Output:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Apple          3.99    10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Banana        12.50     5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Dynamic width and precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">width</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">precision</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%*.*f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">width</span><span class="p">,</span><span class="w"> </span><span class="nx">precision</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">  </span><span class="c1">// Width and precision from variables</span><span class="w">
</span></span></span></code></pre></div><h3 id="structs">Structs</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyStruct</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// Private field (package-visible)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// Public field (exported)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No need for &#34;-&gt;&#34; with struct pointers, Go handles it</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Value receiver method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">myFunc</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">Y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">y</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Pointer receiver method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="o">*</span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">modify</span><span class="p">(</span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">s</span><span class="p">.</span><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">x</span><span class="w">  </span><span class="c1">// Can modify original struct</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Pointer receivers can accept values and pointers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Value receivers can also accept both, Go handles it automatically</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// In a sense, pointer parameters have &#34;broader&#34; acceptance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Struct tags</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">User</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Name</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="s">`json:&#34;name&#34; xml:&#34;user-name&#34;`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Age</span><span class="w">  </span><span class="kt">int</span><span class="w">    </span><span class="s">`json:&#34;age,omitempty&#34;`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Pass</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="s">`json:&#34;-&#34;`</span><span class="w"> </span><span class="c1">// Ignore this field</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Reading tags with reflection</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;reflect&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">field</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nf">TypeOf</span><span class="p">(</span><span class="nx">User</span><span class="p">{}).</span><span class="nf">FieldByName</span><span class="p">(</span><span class="s">&#34;Name&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">field</span><span class="p">.</span><span class="nx">Tag</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;json&#34;</span><span class="p">))</span><span class="w">  </span><span class="c1">// &#34;name&#34;</span><span class="w">
</span></span></span></code></pre></div><h3 id="interfaces">Interfaces</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Interfaces define method signatures</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No explicit implementation needed - types automatically implement interfaces</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Interfaces can embed other interfaces</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInterface</span><span class="w"> </span><span class="kd">interface</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">myAdd</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyStruct</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">myAdd</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// Implements myAdd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">y</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Now MyStruct implements MyInterface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Empty interface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">interface</span><span class="p">{}</span><span class="w"> </span><span class="c1">// or any (Go 1.18+)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Can store any type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="kd">interface</span><span class="p">{}</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Empty struct</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Takes no memory, often used as signal</span><span class="w">
</span></span></span></code></pre></div><h3 id="error-handling">Error Handling</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// error is a built-in interface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="kd">interface</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Functions typically return result and error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">result</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">doSomething</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;couldn&#39;t convert number: %v\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Custom error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyError</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">msg</span><span class="w"> </span><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="nx">MyError</span><span class="p">)</span><span class="w"> </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">e</span><span class="p">.</span><span class="nx">msg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Create errors with errors package</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;errors&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">&#34;something went wrong&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Format errors with fmt.Errorf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;invalid value: %d&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">value</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><h3 id="concurrency">Concurrency</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Use go keyword to start goroutines</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="nf">say</span><span class="p">(</span><span class="s">&#34;world&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">say</span><span class="p">(</span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Need to wait for goroutines to finish</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// See Defer and Channels section for channel creation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Sending to full channel blocks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Receiving from empty channel blocks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Close channel</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">close</span><span class="p">(</span><span class="nx">myChan</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Note: Only senders should close channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Use select to handle multiple channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Like concurrent switch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// select blocks until one case can proceed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// When multiple cases ready, randomly picks one</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">select</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;received from ch1:&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="nx">ch2</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">x</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;sent to ch2&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">quit</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;quit&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;no communication&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Mutex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;sync&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">mu</span><span class="w"> </span><span class="nx">sync</span><span class="p">.</span><span class="nx">Mutex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Critical section</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Use defer to ensure unlock</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Critical section</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Directional channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">send</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="p">}</span><span class="w">      </span><span class="c1">// Send-only</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">recv</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch</span><span class="w"> </span><span class="p">}</span><span class="w">   </span><span class="c1">// Receive-only</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check if channel is closed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="p">,</span><span class="w"> </span><span class="nx">ok</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch</span><span class="w">  </span><span class="c1">// ok is false if channel closed and empty</span><span class="w">
</span></span></span></code></pre></div><h3 id="various-magic-">Various Magic 🪄</h3>
<h4 id="heading"><code>...</code></h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// 1. Variadic functions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">sum</span><span class="p">(</span><span class="nx">nums</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">total</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">nums</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">total</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">n</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">total</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Calling</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">      </span><span class="c1">// Can pass multiple</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w">            </span><span class="c1">// Can pass one</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">()</span><span class="w">             </span><span class="c1">// Can pass none</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 2. Expanding slices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">numbers</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">result</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">sum</span><span class="p">(</span><span class="nx">numbers</span><span class="o">...</span><span class="p">)</span><span class="w">  </span><span class="c1">// Expand to multiple arguments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">combined</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="nx">slice1</span><span class="p">,</span><span class="w"> </span><span class="nx">slice2</span><span class="o">...</span><span class="p">)</span><span class="w">  </span><span class="c1">// Expand slice2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 3. Array literals</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">  </span><span class="c1">// Compiler calculates length, result is [5]int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Useful with indices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="mi">0</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;zero&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="mi">5</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;five&#34;</span><span class="p">,</span><span class="w">   </span><span class="c1">// Array length is 6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Notes:</p>
<ol>
<li>Variadic parameter must be last</li>
<li>Inside function, variadic parameter is slice type</li>
<li>Types must match when expanding</li>
</ol>
<h4 id="initialization-tricks">Initialization Tricks</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Initialize array with indices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="mi">10</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">9</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">}</span><span class="w">  </span><span class="c1">// 0th is 1, 9th is 10, rest are 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Initialize map with keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;a&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;b&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Partial struct initialization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Point</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">X</span><span class="p">,</span><span class="w"> </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">Point</span><span class="p">{</span><span class="nx">Y</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">}</span><span class="w">  </span><span class="c1">// X is 0, Y is 10</span><span class="w">
</span></span></span></code></pre></div><h4 id="iota-enumerations">iota Enumerations</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// iota starts at 0 in each const declaration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">B</span><span class="w">         </span><span class="c1">// 1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">C</span><span class="w">         </span><span class="c1">// 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Skip values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w">  </span><span class="p">=</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 0 (skip)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">KB</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="p">(</span><span class="mi">10</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="kc">iota</span><span class="p">)</span><span class="w">  </span><span class="c1">// 1 &lt;&lt; 10 = 1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">MB</span><span class="w">         </span><span class="c1">// 1 &lt;&lt; 20 = 1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">GB</span><span class="w">         </span><span class="c1">// 1 &lt;&lt; 30 = 1073741824</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Bit flag enums</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Read</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Write</span><span class="w">                        </span><span class="c1">// 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Execute</span><span class="w">                      </span><span class="c1">// 4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Usage</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">perm</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">Read</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">Write</span><span class="w">  </span><span class="c1">// Combine permissions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">perm</span><span class="o">&amp;</span><span class="nx">Read</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Has read permission&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Add permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">perm</span><span class="w"> </span><span class="o">|=</span><span class="w"> </span><span class="nx">Execute</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Remove permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">perm</span><span class="w"> </span><span class="o">&amp;^=</span><span class="w"> </span><span class="nx">Write</span><span class="w">
</span></span></span></code></pre></div><h4 id="type-aliases-vs-type-definitions">Type Aliases vs Type Definitions</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Type alias (Go 1.9+) - completely equivalent</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInt</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// MyInt is int, interchangeable</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type definition - creates new type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInt</span><span class="w"> </span><span class="kt">int</span><span class="w">    </span><span class="c1">// MyInt is new type, cannot assign directly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Example</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Celsius</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Fahrenheit</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="nx">Celsius</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">f</span><span class="w"> </span><span class="nx">Fahrenheit</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">212</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// f = c  // Error! Type mismatch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">f</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nf">Fahrenheit</span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">9</span><span class="o">/</span><span class="mi">5</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">32</span><span class="p">)</span><span class="w">  </span><span class="c1">// Need explicit conversion</span><span class="w">
</span></span></span></code></pre></div><h4 id="make-vs-new">make vs new</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nb">new</span><span class="p">(</span><span class="nx">T</span><span class="p">)</span><span class="w">      </span><span class="c1">// Returns *T, zero value allocation; commonly for simple structs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">make</span><span class="p">(</span><span class="o">...</span><span class="p">)</span><span class="w">   </span><span class="c1">// Only for slice/map/chan, returns initialized value (not pointer)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Examples</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">new</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="w">           </span><span class="c1">// *int, value is 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">     </span><span class="c1">// []int, length 5, initialized</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// map[string]int, initialized</span><span class="w">
</span></span></span></code></pre></div><h3 id="go-gotchas-and-important-notes">Go Gotchas and Important Notes</h3>
<h4 id="slice-underlying-array-sharing">Slice Underlying Array Sharing</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Passing slice copies slice header (pointer, len, cap), shares underlying array</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">s</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span><span class="w">         </span><span class="c1">// Shares underlying array with s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w">   </span><span class="c1">// May trigger reallocation, t no longer shares</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Modifying shared underlying array</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span><span class="w">  </span><span class="c1">// [2, 3]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">99</span><span class="w">    </span><span class="c1">// s becomes [1, 99, 3, 4, 5]</span><span class="w">
</span></span></span></code></pre></div><h4 id="map-randomness">Map Randomness</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Map iteration order is random, don&#39;t rely on order</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&#34;a&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;b&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;c&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">k</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">k</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">  </span><span class="c1">// Order may differ each run</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Cannot take address of map elements</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// &amp;m[&#34;key&#34;]  // Compile error: map values not addressable</span><span class="w">
</span></span></span></code></pre></div><h4 id="string-bytes-vs-characters">String Bytes vs Characters</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// len(string) returns byte count, not character count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">))</span><span class="w">  </span><span class="c1">// 6 (3 bytes per Chinese character)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// for range string iterates by rune (UTF-8 decoded)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%d: %c\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="p">)</span><span class="w">  </span><span class="c1">// 0: 你, 3: 好</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// s[i] gives byte</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%x\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;你&#34;</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="w">  </span><span class="c1">// e4 (first byte)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Strings are immutable, convert to []byte or []rune to modify</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// s[0] = &#39;H&#39;  // Error!</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="sc">&#39;H&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">string</span><span class="p">(</span><span class="nx">bs</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;Hello&#34;</span><span class="w">
</span></span></span></code></pre></div><h4 id="interface-nil-pitfall">Interface nil Pitfall</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Interface value is (type, data) pair</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// When type != nil, even if data == nil, interface is not nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyErr</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">*</span><span class="nx">MyErr</span><span class="p">)</span><span class="w"> </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&#34;error&#34;</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="kt">error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w">  </span><span class="c1">// true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">pe</span><span class="w"> </span><span class="o">*</span><span class="nx">MyErr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">e</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">pe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w">  </span><span class="c1">// false! type=*MyErr, data=nil</span><span class="w">
</span></span></span></code></pre></div><h4 id="loop-variable-pitfall">Loop Variable Pitfall</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Loop variables reuse same memory location</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Be careful in goroutines/closures</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Wrong</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">  </span><span class="c1">// May all print 2, 3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Correct: rebind</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w">  </span><span class="c1">// Create new local variables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h4 id="method-call-auto-conversion">Method Call Auto-conversion</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Compiler automatically handles value/pointer conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">S</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="o">*</span><span class="nx">S</span><span class="p">)</span><span class="w"> </span><span class="nf">Inc</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">n</span><span class="o">++</span><span class="w"> </span><span class="p">}</span><span class="w">  </span><span class="c1">// Pointer receiver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="nx">S</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="p">.</span><span class="nf">Inc</span><span class="p">()</span><span class="w">    </span><span class="c1">// Compiler converts to (&amp;v).Inc()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">S</span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">(</span><span class="o">*</span><span class="nx">p</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w"> </span><span class="c1">// Works but unnecessary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="p">.</span><span class="nf">Inc</span><span class="p">()</span><span class="w">    </span><span class="c1">// Direct call</span><span class="w">
</span></span></span></code></pre></div><h4 id="struct-embedding-anonymous-fields">Struct Embedding (Anonymous Fields)</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Embedded field methods and properties are &#34;promoted&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">A</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">X</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="w"> </span><span class="nx">A</span><span class="p">)</span><span class="w"> </span><span class="nf">Show</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">X</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">B</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w">          </span><span class="c1">// Anonymous embedding</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="nx">B</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">b</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w">        </span><span class="c1">// Direct access, equivalent to b.A.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">b</span><span class="p">.</span><span class="nf">Show</span><span class="p">()</span><span class="w">       </span><span class="c1">// Calls A&#39;s method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// With name conflicts, must specify explicitly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">C</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">X</span><span class="w"> </span><span class="kt">int</span><span class="w">      </span><span class="c1">// Shadows A.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="nx">C</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">c</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w">        </span><span class="c1">// Accesses C.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">c</span><span class="p">.</span><span class="nx">A</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">2</span><span class="w">      </span><span class="c1">// Accesses A.X</span><span class="w">
</span></span></span></code></pre></div><h4 id="init-functions-and-package-imports">init Functions and Package Imports</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// init() executes automatically on package load</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Order: imported package init -&gt; current package init -&gt; main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w"> </span><span class="s">&#34;database/sql&#34;</span><span class="w">      </span><span class="c1">// Only execute init, don&#39;t use exports</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w"> </span><span class="s">&#34;github.com/go-sql-driver/mysql&#34;</span><span class="w">  </span><span class="c1">// Register MySQL driver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">init</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;main init&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Database driver already registered in init</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Basic Makefile</title><link>https://www.parkerchenca.com/tech/basic-makefile/</link><pubDate>Thu, 10 Sep 2026 11:23:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/basic-makefile/</guid><description>The first step to understand makefile</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I often noticed Makefile files in the root directory when browsing open-source projects on GitHub. For a long time, I thought it was some kind of sophisticated &ldquo;magic tool&rdquo;. So during my spare time at my internship, I decided to learn some basic syntax&hellip; only to discover that it&rsquo;s actually like a &ldquo;recipe&rdquo; for compilation - to get a target file (the dish), you need some dependencies (ingredients) and commands (cooking instructions). Anyway, at least now I can understand it (mostly).</p>
</blockquote>
<h2 id="make">Make</h2>
<h3 id="basic-rules">Basic Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">target</span><span class="o">:</span> <span class="n">dependencies</span> ..
</span></span><span class="line"><span class="cl"><span class="err">[tab][Command]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">TARGET</span> <span class="o">=</span> main
</span></span><span class="line"><span class="cl"><span class="nf">main</span><span class="o">:</span> <span class="n">hello</span>.<span class="n">o</span> <span class="n">world</span>.<span class="n">o</span>   <span class="c"># will be run by default as the first target
</span></span></span><span class="line"><span class="cl">    gcc $^ -o <span class="k">$(</span>TARGET<span class="k">)</span> <span class="c1"># treat these as normal bash commands</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">hello.o</span><span class="o">:</span> <span class="n">hello</span>.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c hello.c      <span class="c1"># -c for compile only</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">world.o</span><span class="o">:</span> <span class="n">world</span>.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c world.c
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span>                  <span class="c"># will not be run unless &#34;make clean&#34;
</span></span></span><span class="line"><span class="cl">    rm -f <span class="k">$(</span>wildcard *.o<span class="k">)</span> <span class="k">$(</span>TARGET<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span>
</span></span></code></pre></div><h3 id="common-cli-parameters">Common CLI Parameters</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">-v</span>
</span></span><span class="line"><span class="cl"><span class="err">-n</span> <span class="err">--just-print</span>        <span class="c"># Print commands without executing
</span></span></span><span class="line"><span class="cl"><span class="err">-p</span>                     <span class="c"># Output makefile data (lots of info)
</span></span></span><span class="line"><span class="cl"><span class="err">-t</span> <span class="err">--touch</span>             <span class="c"># Update file timestamps without changing targets (dry run)
</span></span></span><span class="line"><span class="cl"><span class="err">-q</span> <span class="err">--question</span>          <span class="c"># Check if target exists. Do nothing if yes, print error if no
</span></span></span><span class="line"><span class="cl">                       <span class="c1"># Usually used with -qp</span>
</span></span><span class="line"><span class="cl"><span class="err">-W</span> <span class="err">--what-if</span> <span class="err">&lt;file&gt;</span>    <span class="c"># Pretend this file was just modified, trigger related rules
</span></span></span><span class="line"><span class="cl"><span class="err">-B</span>                     <span class="c"># Rebuild everything
</span></span></span><span class="line"><span class="cl"><span class="err">-b</span> <span class="err">-m</span>                  <span class="c"># Used to ignore compatibility between different make versions
</span></span></span><span class="line"><span class="cl"><span class="nv">-debug</span><span class="o">=[</span>option<span class="o">]</span>        <span class="c1"># Debug mode</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># option can be: a(all), b(basic), v(verbose)</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># i(implicit), j(jobs), m(makefile)</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># -d = -debug=a</span>
</span></span><span class="line"><span class="cl"><span class="err">-e</span> <span class="nv">var</span><span class="o">=</span>sth             <span class="c1"># Override environment variable values</span>
</span></span><span class="line"><span class="cl"><span class="err">-h</span>                     <span class="c"># Help me!
</span></span></span><span class="line"><span class="cl"><span class="err">-f</span> <span class="err">&lt;file&gt;</span>              <span class="c"># Execute specific makefile
</span></span></span><span class="line"><span class="cl"><span class="err">-i</span>                     <span class="c"># Ignore errors
</span></span></span><span class="line"><span class="cl"><span class="err">-I</span> <span class="err">--include-dir</span> <span class="err">&lt;dir&gt;</span> <span class="c"># Specify make search directory
</span></span></span><span class="line"><span class="cl"><span class="err">-k</span> <span class="err">--keep-going</span>        <span class="c"># Continue on errors, except missing dependencies
</span></span></span><span class="line"><span class="cl"><span class="err">-s</span> <span class="err">--silent</span>
</span></span><span class="line"><span class="cl"><span class="err">-j</span> <span class="err">--jobs</span>              <span class="c"># Parallel compilation when dependencies allow
</span></span></span><span class="line"><span class="cl">                       <span class="c1"># make will try to parallelize as much as possible by default</span>
</span></span></code></pre></div><h3 id="special-syntax">Special Syntax</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="k">$&lt;</span>                  <span class="c"># First item in dependencies
</span></span></span><span class="line"><span class="cl">                    <span class="c1"># Note: if target is matched via %,</span>
</span></span><span class="line"><span class="cl">                    <span class="c1"># $&lt; represents all matched items</span>
</span></span><span class="line"><span class="cl"><span class="err">$^</span>                  <span class="c"># All dependencies
</span></span></span><span class="line"><span class="cl"><span class="k">$?</span>                  <span class="c"># All dependencies that are newer than target
</span></span></span><span class="line"><span class="cl"><span class="k">$+</span>                  <span class="c"># All dependencies without deduplication
</span></span></span><span class="line"><span class="cl"><span class="k">$*</span>                  <span class="c"># The part matched by %
</span></span></span><span class="line"><span class="cl"><span class="k">$@</span>                  <span class="c"># The target
</span></span></span><span class="line"><span class="cl"><span class="k">$%</span>                  <span class="c"># Target member name (only for archive files)
</span></span></span><span class="line"><span class="cl"><span class="k">$$</span>                  <span class="c"># Escape $ character
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">wildcard</span> *.<span class="nv">c</span><span class="k">)</span>     <span class="c"># Use wildcards
</span></span></span><span class="line"><span class="cl"><span class="nf">$(source</span><span class="o">:</span>.<span class="n">c</span>=.<span class="n">o</span>)     <span class="c"># Change suffix of variable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">:=</span>                  <span class="c"># Immediate expansion of $() expressions (no variable hoisting)
</span></span></span><span class="line"><span class="cl"><span class="err">?=</span>                  <span class="c"># Assign only if not already defined
</span></span></span><span class="line"><span class="cl"><span class="err">+=</span>                  <span class="c"># Append to variable value (with leading space)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">%</span>                   <span class="c"># Wildcard in pattern rules
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">@[command]</span>          <span class="c"># Execute command silently
</span></span></span><span class="line"><span class="cl"><span class="err">-[command]</span>          <span class="c"># Ignore errors, continue running
</span></span></span><span class="line"><span class="cl"><span class="err">[command];[command]</span> <span class="c"># Similar to pipeline (&#34;|&#34;)
</span></span></span><span class="line"><span class="cl">                    <span class="c1"># If written on separate lines, executed separately</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">override var </span><span class="o">:</span>= <span class="n">new</span>-<span class="n">value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># $ with uppercase D(Directory) and F(File)
</span></span></span><span class="line"><span class="cl"><span class="c"># Further specify the scope of dependency strings
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">dir/foo.o</span><span class="o">:</span> ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Need parentheses to avoid ambiguity
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>@<span class="nv">D</span><span class="k">)</span>               <span class="c"># dir/foo.o -&gt; dir
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>@<span class="nv">F</span><span class="k">)</span>               <span class="c"># dir/foo.o -&gt; foo.o
</span></span></span></code></pre></div><h3 id="pattern-rules">Pattern Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">%.o</span><span class="o">:</span> %.<span class="n">c</span>    <span class="c"># % means &#34;match&#34;, represents &#34;any string&#34;
</span></span></span><span class="line"><span class="cl">            <span class="c1"># Meaning: to build .o file, its dependency is corresponding .c file</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># No directory search performed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Study these examples for better understanding
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">src/eat</span>
</span></span><span class="line"><span class="cl"><span class="err">e%t</span>
</span></span><span class="line"><span class="cl"><span class="err">%</span> <span class="err">-&gt;</span> <span class="err">src/a</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># then, % is passed to another place...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">c%r</span> <span class="err">-&gt;</span> <span class="err">csrc/ar</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># but if there is a nested % pattern on the original side...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">c%r</span> <span class="err">-&gt;</span> <span class="err">src/car</span>  <span class="c"># % should be &#34;src/a&#34;
</span></span></span><span class="line"><span class="cl">                <span class="c1"># but &#34;src/&#34; will be removed before matching patterns</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># so in this situation, % is &#34;a&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># this rule also applies to the first step</span>
</span></span></code></pre></div><h3 id="functions">Functions</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Basic syntax
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>&lt;<span class="nv">function</span>&gt; &lt;<span class="nv">arguments</span>&gt;<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Can also be written as
</span></span></span><span class="line"><span class="cl"><span class="err">${&lt;function&gt;</span> <span class="err">&lt;arguments&gt;}</span>   <span class="c"># Perhaps more readable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">patsubst</span> %.<span class="nv">c</span>,%.<span class="nv">o</span>,<span class="k">$(</span><span class="nv">source</span><span class="k">))</span>  <span class="c"># Better demonstrates % syntax behavior
</span></span></span><span class="line"><span class="cl">                               <span class="c1"># patsubst = pattern substitute</span>
</span></span><span class="line"><span class="cl">                               <span class="c1"># For any .c file, replace with corresponding .o file</span>
</span></span><span class="line"><span class="cl">                               <span class="c1"># Scope is $(source), which should be text</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Common functions
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">subst</span> <span class="err">&lt;from&gt;,&lt;to&gt;,&lt;text&gt;</span>    <span class="c"># Substitute text
</span></span></span><span class="line"><span class="cl"><span class="err">strip</span> <span class="err">&lt;text&gt;</span>                <span class="c"># Remove spaces
</span></span></span><span class="line"><span class="cl"><span class="err">findstring</span> <span class="err">&lt;find&gt;,&lt;in&gt;</span>      <span class="c"># Find substring, return &lt;find&gt; if found
</span></span></span><span class="line"><span class="cl"><span class="err">filter</span> <span class="err">&lt;pattern...&gt;,&lt;text&gt;</span>  <span class="c"># Can pass multiple patterns
</span></span></span><span class="line"><span class="cl"><span class="err">filter-out</span> <span class="err">&lt;pattern...&gt;,&lt;text&gt;</span> <span class="c"># Reverse filter, keeps unmatched items
</span></span></span><span class="line"><span class="cl"><span class="err">sort</span> <span class="err">&lt;list&gt;</span>                 <span class="c"># Default ascending order
</span></span></span><span class="line"><span class="cl"><span class="err">word</span> <span class="err">&lt;n&gt;,&lt;text&gt;</span>             <span class="c"># Get nth word (a.c b.c c.c -&gt; b.c)
</span></span></span><span class="line"><span class="cl"><span class="err">wordlist</span> <span class="err">&lt;s&gt;,&lt;e&gt;,&lt;text&gt;</span>     <span class="c"># Slice
</span></span></span><span class="line"><span class="cl"><span class="err">words</span> <span class="err">&lt;text&gt;</span>                <span class="c"># Count words
</span></span></span><span class="line"><span class="cl"><span class="err">firstword</span> <span class="err">&lt;text&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">dir</span> <span class="err">&lt;names...&gt;</span>              <span class="c"># Extract directory from filename
</span></span></span><span class="line"><span class="cl"><span class="err">notdir</span> <span class="err">&lt;names...&gt;</span>           <span class="c"># Remove directory part, keep filename only
</span></span></span><span class="line"><span class="cl"><span class="err">suffix</span> <span class="err">&lt;names...&gt;</span>           <span class="c"># Extract suffix
</span></span></span><span class="line"><span class="cl"><span class="err">basename</span> <span class="err">&lt;names...&gt;</span>         <span class="c"># Extract name without suffix (prefix)
</span></span></span><span class="line"><span class="cl"><span class="err">addsuffix</span> <span class="err">&lt;suffix&gt;,&lt;names...&gt;</span> <span class="c"># Add suffix
</span></span></span><span class="line"><span class="cl"><span class="err">addprefix</span> <span class="err">&lt;prefix&gt;,&lt;names...&gt;</span>
</span></span><span class="line"><span class="cl"><span class="err">join</span> <span class="err">&lt;list1&gt;,&lt;list2&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">origin</span> <span class="err">&lt;variable&gt;</span>           <span class="c"># Where did this variable come from?
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">shell</span> <span class="err">&lt;command&gt;</span>             <span class="c"># Execute command in shell
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">error</span> <span class="err">&lt;text</span> <span class="err">...&gt;</span>            <span class="c"># Generate error message, but doesn&#39;t abort
</span></span></span><span class="line"><span class="cl"><span class="err">warning</span> <span class="err">&lt;text</span> <span class="err">...&gt;</span>          <span class="c"># Generate warning message
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Iteration
</span></span></span><span class="line"><span class="cl"><span class="err">foreach</span> <span class="err">&lt;var&gt;,&lt;list&gt;,&lt;text&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">names</span> <span class="o">:=</span> a b c d
</span></span><span class="line"><span class="cl"><span class="nv">files</span> <span class="o">:=</span> <span class="k">$(</span>foreach n,<span class="k">$(</span>names<span class="k">)</span>,<span class="k">$(</span>n<span class="k">)</span>.o<span class="k">)</span>  <span class="c1"># a.o b.o c.o d.o</span>
</span></span></code></pre></div><h3 id="custom-functions-with-call">Custom Functions with call</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">call</span> <span class="err">&lt;expression&gt;,&lt;parm1&gt;,&lt;parm2&gt;,...,&lt;parmn&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Examples are easier to understand
</span></span></span><span class="line"><span class="cl"><span class="nv">reverse</span> <span class="o">=</span> <span class="k">$(</span>2<span class="k">)</span> <span class="k">$(</span>1<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">foo</span> <span class="o">=</span> <span class="k">$(</span>call reverse,a,b<span class="k">)</span>  <span class="c1"># $(foo) -&gt; b a</span>
</span></span></code></pre></div><h3 id="special-variables">Special Variables</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">VPATH</span>                            <span class="c"># Set default search path
</span></span></span><span class="line"><span class="cl"><span class="c"># Syntax: vpath &lt;pattern&gt; &lt;directories&gt;
</span></span></span><span class="line"><span class="cl"><span class="c"># Example: vpath %.h src:../headers:lib  # Directories separated by colon (:)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Can actively set paths
</span></span></span><span class="line"><span class="cl"><span class="c"># Advantage: if file not found, will search in VPATH
</span></span></span><span class="line"><span class="cl"><span class="nv">VPATH</span> <span class="o">=</span> src
</span></span><span class="line"><span class="cl"><span class="nv">BUILD_DIR</span> <span class="o">=</span> build
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">$(BUILD_DIR)/%.o</span><span class="o">:</span> %.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c $&lt; -o <span class="nv">$@</span>
</span></span></code></pre></div><h3 id="sub-makefiles">Sub-Makefiles</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">subsystem</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">cd</span> subdir <span class="o">&amp;&amp;</span> <span class="k">$(</span>MAKE<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Equivalent to
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">subsystem</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">$(</span>MAKE<span class="k">)</span> -C subdir
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Execute make in subsystem
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">export </span><span class="nv">VAR</span> <span class="o">=</span> value     <span class="c1"># Pass VAR to subsystem</span>
</span></span><span class="line"><span class="cl"><span class="err">un</span><span class="k">export </span><span class="err">VAR_PRIVATE</span>   <span class="c"># Don&#39;t pass this variable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># $(SHELL) and $(MAKEFLAGS) are always passed to subsystems
</span></span></span></code></pre></div><h3 id="define-directive">Define Directive</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">define</span> <span class="err">reusable</span>
</span></span><span class="line"><span class="cl"><span class="err">dosth..</span>
</span></span><span class="line"><span class="cl"><span class="err">dosth..</span>
</span></span><span class="line"><span class="cl"><span class="err">endef</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">reusable</span><span class="k">)</span>
</span></span></code></pre></div><h3 id="conditionals">Conditionals</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Similar to bash syntax
</span></span></span><span class="line"><span class="cl"><span class="err">ifeq</span> <span class="err">(var1,</span> <span class="err">var2)</span>
</span></span><span class="line"><span class="cl">    <span class="err">[command]</span>
</span></span><span class="line"><span class="cl"><span class="err">else</span>
</span></span><span class="line"><span class="cl">    <span class="err">[command]</span>
</span></span><span class="line"><span class="cl"><span class="err">endif</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Available keywords
</span></span></span><span class="line"><span class="cl"><span class="err">ifeq</span> <span class="err">ifneq</span> <span class="err">ifdef</span> <span class="err">ifndef</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># if as a function
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">if</span> &lt;<span class="nv">condition</span>&gt;,&lt;<span class="nv">then</span>-<span class="nv">part</span>&gt;<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">if</span> &lt;<span class="nv">condition</span>&gt;,&lt;<span class="nv">then</span>-<span class="nv">part</span>&gt;,&lt;<span class="nv">else</span>-<span class="nv">part</span>&gt;<span class="k">)</span>
</span></span></code></pre></div><h3 id="implicit-rules">Implicit Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Implicit rules use these predefined variables:
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">CC</span> <span class="o">=</span> gcc        <span class="c1"># C compiler</span>
</span></span><span class="line"><span class="cl"><span class="nv">CXX</span> <span class="o">=</span> g++       <span class="c1"># C++ compiler</span>
</span></span><span class="line"><span class="cl"><span class="nv">CFLAGS</span> <span class="o">=</span>        <span class="c1"># C compile options</span>
</span></span><span class="line"><span class="cl"><span class="nv">CXXFLAGS</span> <span class="o">=</span>      <span class="c1"># C++ compile options</span>
</span></span><span class="line"><span class="cl"><span class="nv">LDFLAGS</span> <span class="o">=</span>       <span class="c1"># Linker options</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Only need to define dependencies, compile rules apply automatically
</span></span></span><span class="line"><span class="cl"><span class="nv">CFLAGS</span> <span class="o">=</span> -Wall -O2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">main</span><span class="o">:</span> <span class="n">main</span>.<span class="n">o</span> <span class="n">utils</span>.<span class="n">o</span>  <span class="c"># Implicit rules automatically compile .c → .o
</span></span></span><span class="line"><span class="cl">    <span class="k">$(</span>CC<span class="k">)</span> $^ -o <span class="nv">$@</span>    <span class="c1"># Linking rules need to be written manually</span>
</span></span><span class="line"><span class="cl">                      <span class="c1"># (implicit rules only handle single file compilation)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># View all implicit rules
</span></span></span><span class="line"><span class="cl"><span class="err">make</span> <span class="err">-p</span> <span class="err">|</span> <span class="err">grep</span> <span class="s2">&#34;^%&#34;</span>  <span class="c"># Display all pattern rules
</span></span></span></code></pre></div><h3 id="include-directive">Include Directive</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">include</span> <span class="err">file1.mk</span> <span class="err">file2.mk</span>
</span></span><span class="line"><span class="cl"><span class="err">-include</span> <span class="err">optional.mk</span>  <span class="c"># Don&#39;t error if file doesn&#39;t exist
</span></span></span></code></pre></div><h3 id="special-targets">Special Targets</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span> <span class="n">test</span> <span class="n">install</span>      <span class="c"># Declare phony targets
</span></span></span><span class="line"><span class="cl"><span class="nf">.PRECIOUS</span><span class="o">:</span> %.<span class="n">o</span>                  <span class="c"># Preserve intermediate files
</span></span></span><span class="line"><span class="cl"><span class="nf">.SECONDARY</span><span class="o">:</span>                     <span class="c"># All intermediate files are secondary
</span></span></span><span class="line"><span class="cl"><span class="nf">.DELETE_ON_ERROR</span><span class="o">:</span>               <span class="c"># Delete target file if command errors
</span></span></span></code></pre></div><h3 id="tips-and-tricks">Tips and Tricks</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">all</span><span class="o">:</span> <span class="k">$(</span><span class="nv">object</span><span class="k">)</span>                      <span class="c"># make finds dependencies then executes commands
</span></span></span><span class="line"><span class="cl">                                    <span class="c1"># doesn&#39;t have to compile to &#39;all&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nf">$(object) </span><span class="o">:</span> ...
</span></span><span class="line"><span class="cl">    ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">gcc</span> <span class="err">-MM</span> <span class="err">hello.c</span>                     <span class="c"># Find header dependencies for hello.c
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">dev</span><span class="o">:</span> <span class="n">mymodule</span>.<span class="n">so</span>
</span></span><span class="line"><span class="cl">    @echo <span class="s2">&#34;Development build complete&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">test</span><span class="o">:</span> <span class="n">dev</span>                           <span class="c"># Set prerequisite tasks for multi-language development
</span></span></span><span class="line"><span class="cl">    <span class="k">$(</span>PYTHON<span class="k">)</span> -c <span class="s2">&#34;import mymodule; print(mymodule.hello())&#34;</span>
</span></span></code></pre></div><hr>
]]></content:encoded></item><item><title>JVM in short</title><link>https://www.parkerchenca.com/tech/jvm-in-short/</link><pubDate>Thu, 10 Sep 2026 11:22:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/jvm-in-short/</guid><description>Super Simplified JVM Notes</description><content:encoded><![CDATA[<h2 id="what-is-the-jvm">What is the JVM?</h2>
<ol>
<li>Java programs need the JVM to run.</li>
<li>Like .NET Framework.</li>
<li>Stands for <strong>Java Virtual Machine</strong>. Java can run on multiple platforms because JVMs are implemented for different systems. So, Java programs can run on any platform that has a JVM (Though JVM may be different).</li>
<li>It executes bytecode, which is translated from Java code.</li>
<li>Oh, and Kotlin code can also be compiled into bytecode.</li>
</ol>
<h2 id="what-are-jre-jdk-and-jar">What are JRE, JDK, and JAR?</h2>
<ol>
<li><strong>JRE</strong> (Java Runtime Environment) – It&rsquo;s what Java needs to run, includes the JVM.</li>
<li><strong>JDK</strong> (Java Development Kit) – The toolkit for Java developers (You need it to do developing things), and it includes the JRE. It also contains the <code>javac</code> compiler, which turns your code into bytecode.</li>
<li><strong>JAR</strong> (Java ARchive) – A zip file specifically for Java programs. If everything’s set up correctly, you can run it directly.</li>
</ol>
<h2 id="what-is-the-jvm-made-of">What is the JVM made of?</h2>
<ol>
<li><strong>Class Loader Subsystem</strong> – Finds your classes.</li>
<li><strong>Runtime Data Area</strong> – Contains the native method stack, Java method stack, method area, PC Registers, and heap.
<ol>
<li>Native Method Stack – For calling code in other languages (mainly C++).</li>
<li>Java Method Stack – For storing Java function call stacks.</li>
<li>PC Registers – Tells the interpreter where to go next. Fact: It’s the only area that won’t throw an <strong>OutOfMemoryError</strong>.</li>
<li>Method Area – Holds class-related info. It’s shared between threads.</li>
<li>Heap – Just the heap, shared between threads.</li>
<li>Anything not explicitly mentioned is thread-private.</li>
</ol>
</li>
<li><strong>Execution Engine</strong> – Interpreter, JIT (Just-In-Time compiler), and GC (Garbage Collector).</li>
<li><strong>Native Method Library</strong>.</li>
</ol>
<h2 id="class-loader-subsystem">Class Loader Subsystem?</h2>
<ol>
<li><strong>MyClass.java</strong> -&gt; Loading (find the class) -&gt; Linking -&gt; Verify, Prepare, Resolve -&gt; Initialization.
<ol>
<li><strong>Verify</strong> – Did you write your class correctly?</li>
<li><strong>Prepare</strong> – Allocates memory for <code>static</code> variables and sets them to default.</li>
<li><strong>Resolve</strong> – Turns symbolic references (names) into direct references (addresses).</li>
</ol>
</li>
</ol>
<h2 id="loading-class-loaders">Loading: Class Loaders</h2>
<p>Everything’s an object in Java, even the classes themselves are loaded by class loader objects.</p>
<ol>
<li><strong>BootStrapClassLoader</strong> – The default loader, it looks in the <code>jre/Lib</code> directory.</li>
<li><strong>ExtClassLoader</strong> – Inherits from <code>BootStrapClassLoader</code> and <code>ClassLoader</code>, looks in <code>jre/Lib/ext</code>.</li>
<li><strong>AppClassLoader</strong> – Inherits from <code>ExtClassLoader</code> and <code>ClassLoader</code>, looks in the working directory.
<ul>
<li>Thanks to the delegation, it will always check the parent loader first, preventing duplicate class loads. If the parent finds a class, it won’t look further.</li>
<li>Can specify the classpath using <code>classpath</code> in the command line.</li>
<li><strong>Tomcat</strong> has its own class loader, which extends <code>ClassLoader</code>.</li>
</ul>
</li>
</ol>
<h2 id="method-area">Method Area?</h2>
<p>Holds the constant pool, method info, and class info.</p>
<h2 id="java-method-stack-jvm-language-stack">Java Method Stack (JVM Language Stack)?</h2>
<p>It has a <strong>local variable table</strong>, <strong>operand stack</strong>, <strong>dynamic linking</strong>, and <strong>method return addresses</strong>. The native method stack is similar but handles methods from other languages.</p>
<ul>
<li><strong>Local Variable Table</strong> – Stores variable names and values.</li>
<li><strong>Operand Stack</strong> – Fetches variables from the local variable table for computation. The value is removed from the variable table when it&rsquo;s being computed.</li>
</ul>
<h2 id="heap">Heap?</h2>
<ul>
<li>Objects live here. Generally, it’s about <code>physical memory / 64</code> in size, maxing out at <code>physical memory / 4</code>.</li>
<li>It’s divided into the <strong>young generation</strong> and the <strong>old generation</strong>, with a default size ratio of 1:2.</li>
<li>The young generation is further divided into the <strong>eden</strong>, <strong>S1</strong>, and <strong>S2</strong> spaces, with a default ratio of 8:1:1.</li>
<li>New objects go into the <strong>eden</strong>. When eden fills up, it triggers a <strong>young/minor GC</strong>. Surviving objects are moved to either <strong>S1</strong> or <strong>S2</strong>.
<ul>
<li>During each GC, survivors in S1 or S2 also get checked. Survivors of the survivor spaces “jump” between <strong>S1</strong> and <strong>S2</strong>.</li>
<li>If an object survives long enough, it moves to the <strong>old generation</strong>.</li>
<li>If an object is too large to fit into eden or S1/S2, it goes directly to the <strong>old generation</strong>.</li>
</ul>
</li>
<li>The old generation is handled by another GC, like <strong>major GC</strong> or <strong>Full GC</strong>.
<ul>
<li><strong>Major GC</strong> is mostly and only done by <strong>CMS method (See below)</strong>, while Full GC will clean the old generation along with everything else.</li>
</ul>
</li>
</ul>
<h2 id="gc">GC?</h2>
<h3 id="how-to-find-garbage">How to Find Garbage?</h3>
<ul>
<li><strong>Reference counting</strong> – Track the number of references to an object. But this can’t handle circular references.</li>
<li><strong>Reachability analysis</strong> – Defines several <strong>GC roots</strong> and traverses the objects from those roots like a tree. Anything unreachable is considered garbage.
<ul>
<li>Possible GC roots include things like currently running methods, constants, and static variables in the method area.</li>
</ul>
</li>
</ul>
<h3 id="how-to-reclaim-garbage">How to Reclaim Garbage?</h3>
<ol>
<li><strong>Mark-Sweep</strong> – Marks the garbage and deletes it.
<ul>
<li>This can lead to memory fragmentation, where there’s not enough contiguous space to allocate new objects.</li>
</ul>
</li>
<li><strong>Copy</strong> – Copies live objects elsewhere, then deletes the whole old memory space.
<ul>
<li>This requires a backup memory space of the same size.</li>
<li>It moves objects, which can take some time.</li>
</ul>
</li>
<li><strong>Mark-Compact</strong> – Marks the garbage and deletes it, then compacts the remaining live objects.
<ul>
<li>It’s the slowest of the three algorithms.</li>
</ul>
</li>
</ol>
<h3 id="how-to-do-it-better">How to Do It Better?</h3>
<p>Generational collection:</p>
<ol>
<li>Objects with short lifetimes (in the young generation) are best handled by the copy algorithm because you can get rid of a lot of garbage quickly.</li>
<li>Long-living objects (in the old generation) generally don&rsquo;t use the copy algorithm and instead rely on other algorithms based on needs.</li>
</ol>
<h2 id="common-gc-algorithms">Common GC Algorithms</h2>
<ol>
<li><strong>Serial GC</strong> – An old algorithm. It pauses work threads, starts a new thread to perform GC, and uses the mark-sweep and mark-compact algorithms.</li>
<li><strong>ParNew GC</strong> – A multithreaded version of Serial GC.</li>
<li><strong>CMS</strong> (<strong>Concurrent Mark-Sweep Garbage Collector</strong>) – Used for the old generation, it uses the mark-sweep method. It minimizes pauses by using initial marking but requires an extra re-marking step to ensure accuracy. <strong>Most of its work happens in parallel with application threads.</strong> It&rsquo;s now considered outdated.</li>
<li><strong>Parallel GC</strong> – Replaces the Serial algorithm and can dynamically adjust memory allocation. It’s the default in JDK 8.</li>
<li><strong>Newer GCs, mainly Full GC</strong>:
<ol>
<li><strong>G1</strong> (Garbage First) – A region-based algorithm that divides memory into 2048 regions. Its strength is that it offers controllable latency. It’s the default in JDK 9. It has final marking and evacuation steps, where most of the time is spent. With the help of initial marking, <strong>the rest of the process happens in parallel with application threads</strong>.</li>
<li><strong>ZGC</strong> – A complex paging-based algorithm. Its unique feature is short STW (Stop-the-World) times, which don’t increase with heap size.</li>
<li><strong>For the new generation GC</strong>, the algorithms are not so straightforward, so you might want to dive deeper into that yourself.</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title>Simple Tree Traversal</title><link>https://www.parkerchenca.com/tech/simple-tree-traversal/</link><pubDate>Thu, 10 Sep 2026 11:21:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/simple-tree-traversal/</guid><description>Understanding the &amp;#39;Movement&amp;#39; within the tree</description><content:encoded><![CDATA[<h2 id="-leaf-similar-trees-leetcode-872">🖋️ Leaf-Similar Trees (Leetcode 872)</h2>
<p><img loading="lazy" src="https://assets.leetcode.com/uploads/2020/09/03/leaf-similar-1.jpg"></p>
<p>In short, we are gonna to compare the leaves between two tree.</p>
<p>First, we should get the elements from the leaves.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Definition for a binary tree node.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># class TreeNode:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#     def __init__(self, val=0, left=None, right=None):</span>
</span></span><span class="line"><span class="cl"><span class="c1">#         self.val = val</span>
</span></span><span class="line"><span class="cl"><span class="c1">#         self.left = left</span>
</span></span><span class="line"><span class="cl"><span class="c1">#         self.right = right</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Solution</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">dfs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root</span><span class="p">,</span> <span class="n">list_para</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span> <span class="o">=</span> <span class="n">root</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="n">curr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">temp</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">while</span> <span class="n">curr</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">temp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">curr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="n">curr</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">left</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="o">//</span> <span class="n">Save</span> <span class="nb">all</span> <span class="n">elements</span> <span class="n">on</span> <span class="n">the</span> <span class="n">left</span> <span class="n">side</span><span class="p">,</span> <span class="n">but</span>
</span></span><span class="line"><span class="cl">            <span class="o">//</span> <span class="n">we</span> <span class="n">only</span> <span class="n">want</span> <span class="n">the</span> <span class="n">leaf</span> <span class="n">element</span><span class="p">,</span> <span class="n">so</span><span class="o">...</span>
</span></span><span class="line"><span class="cl">            <span class="n">curr</span> <span class="o">=</span> <span class="n">temp</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">curr</span><span class="o">.</span><span class="n">left</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">curr</span><span class="o">.</span><span class="n">right</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">list_para</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">curr</span><span class="o">.</span><span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="n">curr</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">//</span> <span class="n">Attention</span> <span class="n">here</span><span class="p">,</span> <span class="n">we</span> <span class="s1">&#39;move&#39;</span> <span class="n">our</span> <span class="s1">&#39;pointer&#39;</span> <span class="n">to</span> <span class="n">the</span> <span class="n">right</span> <span class="n">side</span>
</span></span><span class="line"><span class="cl">            <span class="o">//</span> <span class="n">After</span> <span class="n">we</span> <span class="n">have</span> <span class="n">done</span> <span class="nb">all</span> <span class="n">the</span> <span class="n">things</span> <span class="n">we</span> <span class="n">should</span> <span class="n">do</span> <span class="n">on</span> <span class="n">the</span> <span class="n">left</span> <span class="n">side</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">leafSimilar</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root1</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">TreeNode</span><span class="p">],</span> <span class="n">root2</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">TreeNode</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">l1</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="n">l2</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root1</span><span class="p">,</span> <span class="n">l1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root2</span><span class="p">,</span> <span class="n">l2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">l1</span> <span class="o">==</span> <span class="n">l2</span>
</span></span></code></pre></div><h3 id="recursion-method"><strong>Recursion</strong> Method</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Solution</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">dfs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root</span><span class="p">,</span> <span class="n">list_para</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">root</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">root</span><span class="o">.</span><span class="n">left</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">root</span><span class="o">.</span><span class="n">right</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">list_para</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">//</span> <span class="o">**</span><span class="n">Move</span><span class="o">**</span> <span class="n">to</span> <span class="n">the</span> <span class="n">left</span><span class="p">,</span> <span class="n">do</span> <span class="n">it</span> <span class="n">again</span><span class="p">,</span> <span class="o">**</span><span class="n">until</span> <span class="s1">&#39;root is None&#39;</span><span class="o">**</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">list_para</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">//</span> <span class="n">Left</span> <span class="n">side</span> <span class="n">finished</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="o">//</span> <span class="o">**</span><span class="n">Move</span><span class="o">**</span> <span class="n">to</span> <span class="n">the</span> <span class="n">right</span><span class="p">,</span> <span class="n">do</span> <span class="n">it</span> <span class="n">again</span><span class="p">,</span> <span class="o">**</span><span class="n">until</span> <span class="s1">&#39;root is None&#39;</span><span class="o">**</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">right</span><span class="p">,</span> <span class="n">list_para</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">				 <span class="o">//</span> <span class="n">Right</span> <span class="n">side</span> <span class="n">finished</span><span class="p">,</span> <span class="nb">all</span> <span class="n">required</span> <span class="n">data</span> <span class="ow">is</span> <span class="n">saved</span> <span class="ow">in</span> <span class="n">the</span> <span class="n">list_para</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">leafSimilar</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">root1</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">TreeNode</span><span class="p">],</span> <span class="n">root2</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">TreeNode</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">l1</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="n">l2</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root1</span><span class="p">,</span> <span class="n">l1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">dfs</span><span class="p">(</span><span class="n">root2</span><span class="p">,</span> <span class="n">l2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">l1</span> <span class="o">==</span> <span class="n">l2</span>
</span></span></code></pre></div>]]></content:encoded></item><item><title>Two Ways to Reverse a Singly Linked List</title><link>https://www.parkerchenca.com/tech/two-ways-to-reverse-a-singly-linked-list/</link><pubDate>Thu, 10 Sep 2026 11:20:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/two-ways-to-reverse-a-singly-linked-list/</guid><description>&lt;h2 id="0-structure-of-a-singly-linked-list"&gt;0. Structure of a Singly Linked List&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="1-move-pointers"&gt;1. Move pointers&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverseList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="c1"&gt;# Save next node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="c1"&gt;# Reverse the pointer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="c1"&gt;# Move prev forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="c1"&gt;# Move curr forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="c1"&gt;# New head of the reversed list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;0:
1 -&amp;gt; None 2 -&amp;gt; 3 -&amp;gt; 4 -&amp;gt; 5 -&amp;gt; NULL&lt;/p&gt;
&lt;p&gt;1:
2 -&amp;gt; 1 -&amp;gt; None 3 -&amp;gt; 4 -&amp;gt; 5 -&amp;gt; NULL&lt;/p&gt;</description><content:encoded><![CDATA[<h2 id="0-structure-of-a-singly-linked-list">0. Structure of a Singly Linked List</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="nb">next</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">val</span> <span class="o">=</span> <span class="n">val</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">next</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">//</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">3</span> <span class="o">-&gt;</span> <span class="mi">4</span> <span class="o">-&gt;</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="n">NULL</span>
</span></span></code></pre></div><h2 id="1-move-pointers">1. Move pointers</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">reverseList</span><span class="p">(</span><span class="n">head</span><span class="p">:</span> <span class="n">ListNode</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="n">curr</span> <span class="o">=</span> <span class="n">head</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">curr</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span>    <span class="c1"># Save next node</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">prev</span>    <span class="c1"># Reverse the pointer</span>
</span></span><span class="line"><span class="cl">        <span class="n">prev</span> <span class="o">=</span> <span class="n">curr</span>         <span class="c1"># Move prev forward</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span> <span class="o">=</span> <span class="n">temp</span>         <span class="c1"># Move curr forward</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">prev</span>  <span class="c1"># New head of the reversed list</span>
</span></span></code></pre></div><p>0:
1 -&gt; None  2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>1:
2 -&gt; 1 -&gt; None     3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>2:
3 -&gt; 2 -&gt; 1 -&gt; None     4 -&gt; 5 -&gt; NULL</p>
<p>3:
4 -&gt; 3 -&gt; 2 -&gt; 1 -&gt; None     5 -&gt; NULL</p>
<p>4:
5 -&gt; 4 -&gt; 3 -&gt; 2 -&gt; 1 -&gt; None</p>
<hr>
<h2 id="2-head-insertion">2. Head Insertion</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">reverseList</span><span class="p">(</span><span class="n">head</span><span class="p">:</span> <span class="n">ListNode</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span> <span class="o">=</span> <span class="n">ListNode</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">head</span>
</span></span><span class="line"><span class="cl">    <span class="n">curr</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">temp</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">prev</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">temp</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span></code></pre></div><p>0:
1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>1:
<strong>2 -&gt; 1</strong> -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>2:
<strong>3 -&gt; 2 -&gt; 1</strong> -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>3:
<strong>4 -&gt; 3 -&gt; 2 -&gt; 1</strong> -&gt; 5 -&gt; NULL</p>
<p>4:
<strong>5 -&gt; 4 -&gt; 3 -&gt; 2 -&gt; 1</strong> -&gt; NULL</p>
]]></content:encoded></item><item><title>Rust Notes 4</title><link>https://www.parkerchenca.com/tech/rust-notes-4/</link><pubDate>Thu, 10 Sep 2026 11:19:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-4/</guid><description>Range</description><content:encoded><![CDATA[<h2 id="range">Range</h2>
<p>Rather than using C style loop, in Rust, we use ..= to indicate a range:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="mi">5</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">5</span><span class="w">
</span></span></span></code></pre></div><p>Sequences are only allowed for numeric or character types because they can be consecutive.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="sc">&#39;a&#39;</span><span class="o">..=</span><span class="sc">&#39;z&#39;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="char">Char</h3>
<p>Use <code>''</code> . <code>&quot;&quot;</code> is for the string</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;z&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;ℤ&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">cat</span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;😻&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Accept <code>Unicode</code>, occupy 4 bytes.</p>
<h3 id="bool">Bool</h3>
<p>Only 1 byte.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">f</span>: <span class="kt">bool</span> <span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="unit-type">Unit type</h3>
<p>Literally, it is <code>()</code>.</p>
<p>Yes, the unit type is <code>()</code>, and the value of this type is also, and only <code>()</code>.</p>
<p>It&rsquo;s similar to <code>void</code> in other languages.</p>
<p>Sometimes, you may come across code like <code>Result&lt;(), String&gt;</code>. This is an example of <strong>generic types</strong> in Rust. If you&rsquo;re familiar with C++ generic types, you can figure out that we pass 2 types into the <code>Result</code>, regardless of what the <code>Result</code> actually is.</p>
]]></content:encoded></item><item><title>Lagrange Interpolation Method</title><link>https://www.parkerchenca.com/tech/lagrange-interpolation-method/</link><pubDate>Thu, 10 Sep 2026 11:18:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/lagrange-interpolation-method/</guid><description>Imputing new data points within a certain range</description><content:encoded><![CDATA[<h2 id="-starting-from-known-points">🖋️ Starting from known points</h2>
<p>Given the task of constructing a function</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
f(x)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></span><p>that passes through the points</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>P</mi><mn>1</mn></msub><mo stretchy="false">(</mo><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>y</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><msub><mi>P</mi><mn>2</mn></msub><mo stretchy="false">(</mo><msub><mi>x</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>y</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mo>⋯</mo><mtext> </mtext><mo separator="true">,</mo><msub><mi>P</mi><mi>n</mi></msub><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo separator="true">,</mo><msub><mi>y</mi><mi>n</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
P_1(x_1, y_1), P_2(x_2, y_2), \cdots, P_n(x_n, y_n)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span><p>, first let the projection of the <code>i</code> th point onto the <code>x</code> axis be</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msubsup><mi>P</mi><mi>i</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msubsup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
P_i^{\prime}(x_i, 0)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1.0519em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8019em;"><span style="top:-2.453em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span></span><p>Next, consider constructing <code>n</code> functions:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>f</mi><mn>4</mn></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo separator="true">,</mo><msub><mi>f</mi><mn>2</mn></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo separator="true">,</mo><mo>⋯</mo><mtext> </mtext><mo separator="true">,</mo><msub><mi>f</mi><mi>n</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
f_4(x), f_2(x), \cdots, f_n(x)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3011em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1514em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></span><p>such that for the <code>i</code> th function</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>f</mi><mi>i</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
f_i(x)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></span><p>its graph passes through</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo fence="true">{</mo><mtable rowspacing="0.36em" columnalign="left left" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><msubsup><mi>P</mi><mi>j</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msubsup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>j</mi></msub><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo><mo separator="true">,</mo><mspace width="1em"/><mo stretchy="false">(</mo><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><msub><mi>P</mi><mi>i</mi></msub><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr></mtable></mrow><annotation encoding="application/x-tex">
\begin{cases}
P_j^{\prime}(x_j, 0), \quad (j \neq i) \\
P_i(x_i, y_i)
\end{cases}
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:3em;vertical-align:-1.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">{</span></span><span class="mord"><span class="mtable"><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.69em;"><span style="top:-3.69em;"><span class="pstrut" style="height:3.008em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-2.4413em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.3948em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.0572em;">j</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel"><span class="mrel"><span class="mord katex-vbox"><span class="katex-thinbox"><span class="rlap"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord"><span class="mrel"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak"></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal">i</span><span class="mclose">)</span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.008em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.19em;"><span></span></span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span><p>Thus, we can derive the desired function as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></munderover><msub><mi>f</mi><mi>i</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
f(x) = \sum\limits_{i=1}^{n} f_i(x)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.9291em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6514em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></span><p>We can assume that</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>f</mi><mi>i</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi><mo>⋅</mo><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
f_i(x) = a \cdot \prod_{j \neq i} (x - x_j)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:0.4445em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.4882em;vertical-align:-1.4382em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.05em;"><span style="top:-1.8479em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∏</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4382em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:1.0361em;vertical-align:-0.2861em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span><p>By substituting the point</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>y</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">
P_i(x_i, y_i)
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1389em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1389em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span><p>we find that</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mstyle scriptlevel="0" displaystyle="true"><mfrac><msub><mi>y</mi><mi>i</mi></msub><mrow><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub><mo stretchy="false">)</mo></mrow></mfrac></mstyle></mrow><annotation encoding="application/x-tex">
a = \dfrac{y_i}{\prod_{j \neq i} (x_i - x_j)}
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:0.4306em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.2294em;vertical-align:-1.1218em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.1076em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop"><span class="mop op-symbol small-op" style="position:relative;top:0em;">∏</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1864em;"><span style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4358em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.1218em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span><p>Therefore</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>f</mi><mi>i</mi></msub><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msub><mi>y</mi><mi>i</mi></msub><mo>⋅</mo><mstyle scriptlevel="0" displaystyle="true"><mfrac><mrow><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub><mo stretchy="false">)</mo></mrow><mrow><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub><mo stretchy="false">)</mo></mrow></mfrac></mstyle><mo>=</mo><msub><mi>y</mi><mi>i</mi></msub><mo>⋅</mo><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mstyle scriptlevel="0" displaystyle="true"><mfrac><mrow><mi>x</mi><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub></mrow><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub></mrow></mfrac></mstyle></mrow><annotation encoding="application/x-tex">
f_i(x) = y_i \cdot \dfrac{\prod_{j \neq i} (x - x_j)}{\prod_{j \neq i} (x_i - x_j)} = y_i \cdot \prod_{j \neq i} \dfrac{x - x_j}{x_i - x_j}
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:0.6389em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.6976em;vertical-align:-1.1218em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5758em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop"><span class="mop op-symbol small-op" style="position:relative;top:0em;">∏</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1864em;"><span style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4358em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.8258em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop"><span class="mop op-symbol small-op" style="position:relative;top:0em;">∏</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1864em;"><span style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4358em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.1218em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:0.6389em;vertical-align:-0.1944em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.6986em;vertical-align:-1.4382em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.05em;"><span style="top:-1.8479em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∏</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4382em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2603em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9721em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span><p>Thus, we obtain the Lagrange interpolation formula as:</p>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></munderover><msub><mi>y</mi><mi>i</mi></msub><mo>⋅</mo><munder><mo>∏</mo><mrow><mi>j</mi><mo mathvariant="normal">≠</mo><mi>i</mi></mrow></munder><mstyle scriptlevel="0" displaystyle="true"><mfrac><mrow><mi>x</mi><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub></mrow><mrow><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub></mrow></mfrac></mstyle></mrow><annotation encoding="application/x-tex">
f(x) = \sum_{i=1}^{n} y_i \cdot \prod_{j \neq i} \dfrac{x - x_j}{x_i - x_j}
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="katex-base"><span class="katex-strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.1076em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.9291em;vertical-align:-1.2777em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6514em;"><span style="top:-1.8723em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2777em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0359em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="katex-base"><span class="katex-strut" style="height:2.6986em;vertical-align:-1.4382em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.05em;"><span style="top:-1.8479em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span><span class="mrel mtight"><span class="mrel mtight"><span class="mord katex-vbox mtight"><span class="katex-thinbox mtight"><span class="rlap mtight"><span class="katex-strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="katex-inner"><span class="mord mtight"><span class="mrel mtight"></span></span></span><span class="katex-fix"></span></span></span></span></span><span class="mspace nobreak mtight"></span><span class="mrel mtight">=</span></span><span class="mord mathnormal mtight">i</span></span></span></span><span style="top:-3.05em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∏</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4382em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2603em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3117em;"><span style="top:-2.55em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="katex-sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.0572em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2861em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9721em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span><p>Here&rsquo;s a breakdown of its components:</p>
<ul>
<li><code>f(x)</code>: The interpolating polynomial</li>
<li><code>n</code>: The number of given points</li>
<li><code>x_i</code>, <code>y_i</code>: The given points through which the polynomial must pass</li>
<li><code>∏</code>: The product symbol, indicating multiplication of terms</li>
</ul>
<p>The formula creates a weighted sum of basis polynomials, each passing through one point and zero at all others. This ensures the resulting polynomial satisfies all given points.</p>
<p>The naive implementation of this algorithm has a time complexity of <code>O(n^2)</code>, but it can be optimized to <code>O(nlog^2n)</code>. For more details, refer to fast polynomial interpolation.</p>
<h2 id="-references">📎 <strong>References</strong></h2>
<ul>
<li><a href="https://oi-wiki.org/math/numerical/interp/#lagrange-%E6%8F%92%E5%80%BC%E6%B3%95">https://oi-wiki.org/math/numerical/interp/#lagrange-插值法</a></li>
</ul>
]]></content:encoded></item><item><title>Leetcode reflection (1)</title><link>https://www.parkerchenca.com/tech/leetcode-reflection-1/</link><pubDate>Thu, 10 Sep 2026 11:17:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/leetcode-reflection-1/</guid><description>Python APIs</description><content:encoded><![CDATA[<h2 id="1732-find-the-highest-altitude">1732. Find the Highest Altitude</h2>
<p>There is a biker going on a road trip. The road trip consists of <code>n + 1</code> points at different altitudes. The biker starts his trip on point <code>0</code> with altitude equal <code>0</code>.</p>
<p>You are given an integer array <code>gain</code> of length <code>n</code> where <code>gain[i]</code> is the <strong>net gain in altitude</strong> between points <code>i</code> and <code>i + 1</code> for all (<code>0 &lt;= i &lt; n)</code>. Return <em>the <strong>highest altitude</strong> of a point.</em></p>
<p><strong>Example 1:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Input: gain = [-5,1,5,0,-7]
</span></span><span class="line"><span class="cl">Output: 1
</span></span><span class="line"><span class="cl">Explanation: The altitudes are [0,-5,-4,1,1,-6]. The highest is 1.
</span></span></code></pre></div><p><strong>Example 2:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Input: gain = [-4,-3,-2,-1,4,3,2]
</span></span><span class="line"><span class="cl">Output: 0
</span></span><span class="line"><span class="cl">Explanation: The altitudes are [0,-4,-7,-9,-10,-6,-3,-1]. The highest is 0.
</span></span></code></pre></div><h3 id="solution">Solution:</h3>
<p>A straightforward question, the major solution is to successively sum 2 Adjacent elements in the list, just like the example.</p>
<p>My first answer is:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Solution</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">largestAltitude</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">gain</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">gain</span><span class="p">)):</span>
</span></span><span class="line"><span class="cl">            <span class="n">gain</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">gain</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="n">fixed</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">gain</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">fixed</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">fixed</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="mi">0</span>
</span></span></code></pre></div><p>Then, I found another one which used the python API:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Solution</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">largestAltitude</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">gain</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="n">accumulate</span><span class="p">(</span><span class="n">gain</span><span class="p">,</span> <span class="n">initial</span> <span class="o">=</span><span class="mi">0</span><span class="p">))</span>
</span></span></code></pre></div><p><strong>One line, and the space complexity is O(1).</strong></p>
<p>My thought after this question is to use Python APIs (such as <code>accumulate()</code>) as much as I can since it probably has been optimized by someone else. Unless I am not so happy with their performance.</p>
]]></content:encoded></item><item><title>Rust Notes 3</title><link>https://www.parkerchenca.com/tech/rust-notes-3/</link><pubDate>Thu, 10 Sep 2026 11:16:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-3/</guid><description>Basic types 1</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
In the end, all data types in Rust come from these primitive types.</p>
</blockquote>
<h2 id="basic-types">Basic types</h2>
<ul>
<li>Every value in Rust has a specific data type</li>
<li>In general, these can be divided into two categories: <strong>scalar</strong> types and <strong>compound</strong> types</li>
<li>Scalar types include:
<ul>
<li><strong>Numbers</strong>: Signed integers (<code>i8</code>, <code>i16</code>, <code>i32</code>, <code>i64</code>, <code>isize</code>), unsigned integers (<code>u8</code>, <code>u16</code>, <code>u32</code>, <code>u64</code>, <code>usize</code>), floating-point numbers (<code>f32</code>, <code>f64</code>)
<ul>
<li>The <code>isize</code> and <code>usize</code> types depend on the architecture of the computer the program is running on: if the CPU is 32-bit, these types are 32-bit; similarly, if the CPU is 64-bit, they are</li>
<li>Rust&rsquo;s <strong>default</strong> integer type is <code>i32</code></li>
<li>Can overflow, and Rust does not check for this by default. If you encounter incorrect values, make sure to check the type of your numbers.</li>
</ul>
</li>
<li><strong>Strings</strong>: String literals and string slices</li>
<li><strong>Booleans</strong>: <code>true</code> and <code>false</code></li>
<li><strong>Characters</strong>: Representing a single Unicode character, stored as 4 bytes</li>
<li><strong>Unit type</strong>: Represented by <code>()</code>, with its only value also being <code>()</code></li>
</ul>
</li>
</ul>
<hr>
<h3 id="be-careful-with-floats">Be Careful with <code>float</code>s</h3>
<p>See this example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="fm">assert!</span><span class="p">(</span><span class="mf">0.1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">0.2</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0.3</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>You might think this would return <code>true</code> , but the truth is, the program will panic and quit.</p>
<ul>
<li>Due to binary precision issues, <code>0.1 + 0.2</code> is not exactly equal to <code>0.3</code></li>
<li>You can consider using this approach: <code>(0.1_f64 + 0.2 - 0.3).abs() &lt; 0.00001</code></li>
</ul>
<hr>
<h3 id="nan">NaN</h3>
<ul>
<li><code>-42.1.sqrt()</code> will produce <code>NaN</code></li>
<li>Any operation involving <code>NaN</code> will return <code>NaN</code></li>
<li>Comparing <code>NaN</code> will cause the code to panic and crash</li>
<li>Use <code>is_nan()</code> to determine if a value is <code>NaN</code></li>
</ul>
<hr>
<h3 id="use"><strong>Use <code>as</code> for Type Conversion</strong></h3>
<p>In Rust, you can use <code>as</code> to convert one type to another.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span>: <span class="kt">f64</span> <span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">f64</span><span class="p">;</span><span class="w"> </span><span class="c1">// Convert i32 to f64
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;x as f64 is: </span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Rust Notes 2</title><link>https://www.parkerchenca.com/tech/rust-notes-2/</link><pubDate>Thu, 10 Sep 2026 11:15:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-2/</guid><description>Basic syntax: variable and function</description><content:encoded><![CDATA[<h2 id="syntax-of-rust">Syntax of Rust</h2>
<p>Don’t worry, this will be very easy at the beginning. (Really?)</p>
<hr>
<h3 id="function-goes-first">Function goes first</h3>
<ul>
<li>Similar to C and C++, there must be a <code>main</code> function as the entry point of the program.</li>
<li>Use <code>fn</code> to declare a function, so concise.</li>
<li>Use <code>()</code> for receiving parameters, and <code>{}</code> for the actual logic inside the function.</li>
<li>Remember to use <code>;</code> to end a statement. As I said, it’s similar to C and C++.</li>
<li>Example:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Hello, world!&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// &#34;ln&#34; means print with a new line after the content
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// What is &#34;!&#34;? Well, it means this function is actually a macro
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// For now, let&#39;s just use it as is
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// You don&#39;t need to learn everything to start using Rust. Heart.
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>A complete structure of function head in Rust should be:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="n">keyword</span><span class="w"> </span><span class="n">name</span><span class="p">(</span><span class="n">parameter</span>: <span class="nc">type</span><span class="w"> </span><span class="p">)</span><span class="w"> </span>-&gt; <span class="p">[</span><span class="k">return</span><span class="w"> </span><span class="k">type</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span>      <span class="nf">myFunction</span><span class="p">(</span><span class="n">para</span><span class="w"> </span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><hr>
<h3 id="define-variables">Define variables</h3>
<ul>
<li>You <strong>must</strong> use <code>let</code> to create a variable.
<ul>
<li><code>let myVar = 3;</code></li>
<li><code>let myVar: u32 = 3;</code> → Explicitly specifies the type of the variable <code>myVar</code> as <code>u32</code>. <code>u32</code> is a 32-bit unsigned integer type in Rust.</li>
<li><code>let mut myVar = 3;</code> → Creates a <strong>mutable</strong> variable.</li>
</ul>
</li>
<li>What? Mutable?
<ul>
<li>Variables in Rust are <strong>immutable by default</strong>.(Its value is determined after compilation.)</li>
<li>It&rsquo;s important to understand that in Rust, <code>some_variable = some_value</code> is not just <strong>assigning</strong> a value, but rather <strong>binding</strong> the value to the variable.</li>
<li>This topic is related to Rust’s Ownership feature, which we will discuss in the next post.</li>
<li>Here&rsquo;s an example:</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">myVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">myVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span><span class="w"> </span><span class="c1">// Error
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">myMutVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">myMutVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span><span class="w"> </span><span class="c1">// Pass
</span></span></span></code></pre></div><ul>
<li>If you understand that variables are bound to values, it becomes easier to grasp <strong>variable destructuring</strong>:
<ul>
<li>Basically, destructuring means extracting values from patterns.</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">b</span><span class="p">)</span>: <span class="p">(</span><span class="kt">bool</span><span class="p">,</span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;a = </span><span class="si">{:?}</span><span class="s">, b = </span><span class="si">{:?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// You can treat the {} as a placeholder for a or b
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// :? is for &#34;formatting&#34; output and &#34;debugging&#34; output
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Whatever, it should print the value of a and b
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">assert_eq!</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><ul>
<li>You can also use <code>const</code> to define a constant value:
<ul>
<li><code>const MY_CONST_VALUE: i32 = 5;</code></li>
<li>Constants must always have a type annotation, unlike regular variables.</li>
</ul>
</li>
</ul>
<hr>
<h4 id="statement-and-expression"><strong>Statement and expression</strong></h4>
<ul>
<li>In short:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">add_with_extra</span><span class="p">(</span><span class="n">x</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span>  <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// Statement
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="c1">// Statement
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="c1">// Expression. Hey! Attention here! No &#34;;&#34; after the sentence!
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Also expression is expected to &#34;return&#34; something
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// So we can avoid to write &#34;return&#34; in the end of our fn
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// In other word, statament CANNOT return a value
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><ul>
<li>Interesting facts:
<ul>
<li>In <code>let x = 1;</code>
<ul>
<li><code>x</code> is an expression</li>
<li><code>1</code> is an expression</li>
<li><code>let x = 1;</code> is a statement</li>
<li>Bound</li>
</ul>
</li>
</ul>
</li>
<li>Lastly, if an expression doesn’t return anything, it returns <code>()</code>
<ul>
<li><code>()</code> is both a type and a value, and the value is <code>()</code>.</li>
<li>You can treat the <code>()</code> as a <code>()</code>, yes, that is it.</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title>Rust Notes 1</title><link>https://www.parkerchenca.com/tech/rust-notes-1/</link><pubDate>Thu, 10 Sep 2026 11:14:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-1/</guid><description>Hello world!</description><content:encoded><![CDATA[<h2 id="about-these-notes">About these notes</h2>
<p>These Rust notes are just a collection of my learning records. Since I&rsquo;m a beginner in Rust, these notes are more like quick references or supplements, rather than a comprehensive Rust tutorial. No matter what, I hope you can still find parts that are useful to you.</p>
<hr>
<h3 id="why-rust">Why rust？</h3>
<p>Rust&rsquo;s advantages include memory safety, high performance, and high productivity. To me, Rust appears to be one of the best implementations of C++. If you don&rsquo;t get into deeper topics and only use prepared libraries, Rust&rsquo;s syntax is simple and clear. Its built-in compiler cautions are also quite informative, which significantly decreases the amount of thinking required on developers.</p>
<p>However, Rust has been criticized for being &ldquo;too safe.&rdquo; If you want to dig deeper and truly utilize Rust, you&rsquo;ll have to deal with its complex and tedious safety mechanisms. A true dilemma exists: &ldquo;Why not use the more flexible C++, or Python, which offers quicker speed in development and a more strong ecosystem?&rdquo;</p>
<p>In my opinion, Rust is a &ldquo;balanced&rdquo; choice that addresses some shortcomings of mainstream languages. It is safer than C++ and performs better than Python. However, Rust has obvious drawbacks including an extremely high learning and development cost (which may be more difficult than learning C++). However, Rust is clearly a popular technology right now, and its ecosystem is rapidly expanding. Learning a challenging new language is never a terrible idea.</p>
<hr>
<h3 id="environment-prep">Environment prep</h3>
<ol>
<li>Follow the instructions at <a href="https://www.rust-lang.org/learn/get-started">https://www.rust-lang.org/learn/get-started</a> to install <strong>Rust</strong>.</li>
<li>Install VS Code.</li>
<li>Install the <strong>rust-analyzer</strong> extension in VS Code.</li>
<li>Well done! You’re now ready to write your first Rust program.</li>
</ol>
<p>Use Google or AI tools to help you do these tasks, you will deal with Google and AI all the time when you’re learning something new.</p>
<hr>
<h3 id="hello-world">Hello world</h3>
<ol>
<li>In VS Code, open a new folder.</li>
<li>Press `Ctrl + `` to open a new terminal, or you can follow the top menu tabs: &ldquo;Terminal&rdquo; -&gt; &ldquo;New Terminal&rdquo;.</li>
<li>Enter <code>cargo new helloworld</code> to create a new project named <code>helloworld</code>.
<ol>
<li><code>cargo</code> is like the <code>pip</code> in Python; it manages packages (libraries) in Rust.</li>
</ol>
</li>
<li>Go into the <code>src</code> folder, and you will find the <code>main.rs</code> file.</li>
<li>Enter <code>cargo run</code> in the terminal to directly run … oops! An error occurs.
<ol>
<li>You need to first navigate into the <code>helloworld</code> directory because that’s the project’s working directory.</li>
<li>Use <code>cd helloworld</code>, or open the folder again in VS Code, and then create a new terminal.</li>
<li>Enter <code>cargo run</code>.</li>
<li>Congratulations! You&rsquo;ve run your first Rust program!</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title>Window Functions in SQL</title><link>https://www.parkerchenca.com/tech/window-functions-in-sql/</link><pubDate>Thu, 10 Sep 2026 11:13:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/window-functions-in-sql/</guid><description>Apply Aggregate Functions to Specific Data</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong></p>
<p>Boss: &ldquo;I need the average sales for 7 days.&rdquo;</p>
<p>Me: &ldquo;Sure! Which 7 days?&rdquo;</p>
<p>Boss: &ldquo;All the 7 days!&rdquo;</p>
<p>Me: &ldquo;Su…Sure…?&rdquo;</p>
</blockquote>
<h2 id="-window-functions">🖋️ Window Functions</h2>
<p>Window functions are generally applied after aggregate functions like <code>MAX()</code>, <code>MIN()</code>, <code>AVG()</code> to perform calculations <strong>across</strong> a set of table rows(days before, days after) that are related to the current row(current day).</p>
<h4 id="example-table-1-employees">Example Table 1: <code>employees</code></h4>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
			</tr>
	</tbody>
</table>
<h4 id="example-1-over-without-partitioning">Example 1: <code>OVER()</code> Without Partitioning</h4>
<p>Calculate the average salary for all employees:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">()</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">avg_salary_all_departments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
					<th><strong>avg_salary_all_departments</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>6250</td>
			</tr>
	</tbody>
</table>
<h4 id="example-2-partition-by">Example 2: <code>PARTITION BY</code></h4>
<p>Calculate the average salary <strong>per</strong> department:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">department_id</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">avg_salary_per_department</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
					<th><strong>avg_salary_per_department</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>7000</td>
			</tr>
	</tbody>
</table>
<h4 id="example-3-order-by-with-ranking">Example 3: <code>ORDER BY</code> with Ranking</h4>
<p>Rank employees <strong>by</strong> salary <strong>within</strong> their departments:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">**</span><span class="n">department_id</span><span class="o">**</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">**</span><span class="n">salary</span><span class="o">**</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="o">**</span><span class="n">salary_rank</span><span class="o">**</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th><strong>department_id</strong></th>
					<th><strong>salary</strong></th>
					<th><strong>salary_rank</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>1</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>2</td>
			</tr>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>3</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>1</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>2</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>3</td>
			</tr>
	</tbody>
</table>
<hr>
<h4 id="example-table-2-orders">Example Table 2: <code>orders</code></h4>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
			</tr>
	</tbody>
</table>
<h4 id="example-4-range-with-date-intervals">Example 4: <code>RANGE</code> with Date Intervals</h4>
<p>Sum the total orders in the last 7 days for <strong>each row</strong>: (INTERVAL 6 because included CURRENT ROW)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_date</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_total</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SUM</span><span class="p">(</span><span class="n">order_total</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">order_date</span><span class="w"> </span><span class="n">RANGE</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="nb">INTERVAL</span><span class="w"> </span><span class="s1">&#39;6&#39;</span><span class="w"> </span><span class="k">DAY</span><span class="w"> </span><span class="n">PRECEDING</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">CURRENT</span><span class="w"> </span><span class="k">ROW</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">sum_last_7_days</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">orders</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
					<th>sum_last_7_days</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
					<td>300</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
					<td>450</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
					<td>700</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
					<td>950</td>
			</tr>
	</tbody>
</table>
<h4 id="example-5-rows-between-preceding-and-following">Example 5: <code>ROWS</code> Between Preceding and Following</h4>
<p>Calculate the sum of order totals for the current row and the 2 preceding rows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_date</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_total</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SUM</span><span class="p">(</span><span class="n">order_total</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">order_date</span><span class="w"> </span><span class="k">ROWS</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">PRECEDING</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">CURRENT</span><span class="w"> </span><span class="k">ROW</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">sum_last_3_orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">orders</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
					<th>sum_last_3_orders</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
					<td>300</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
					<td>450</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
					<td>600</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
					<td>700</td>
			</tr>
	</tbody>
</table>
<hr>
<h4 id="references-sheet">References sheet</h4>
<p>After max()…</p>
<ul>
<li><strong>OVER(…)</strong>: Applied <strong>over</strong> &hellip;</li>
<li><strong>PARTITION BY</strong>: Used to <strong>divide by</strong> &hellip;</li>
<li><strong>ORDER BY</strong> [DESC]</li>
<li><strong>ROWS</strong> <code>[BETWEEN...AND]</code>
<ol>
<li><code>n PRECEDING</code></li>
<li><code>n FOLLOWING</code></li>
<li><code>CURRENT ROW</code></li>
<li><code>UNBOUNDED PRECEDING</code> All before</li>
<li><code>UNBOUNDED FOLLOWING</code> All after</li>
</ol>
</li>
<li><strong>RANGE</strong> <code>[BETWEEN...AND]</code>
<ol>
<li><code>INTERVAL 'n' DAY</code></li>
</ol>
</li>
</ul>
]]></content:encoded></item><item><title>Move Zeroes: Understanding Parameter Behavior in Python</title><link>https://www.parkerchenca.com/tech/move-zeroes-understanding-parameter-behavior-in-python/</link><pubDate>Thu, 10 Sep 2026 11:12:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/move-zeroes-understanding-parameter-behavior-in-python/</guid><description>Leetcode Problem Notes, Two-pointer Optimization</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
When addressing the &ldquo;Move Zeroes&rdquo; problem, it is simple to misinterpret Python&rsquo;s parameter behavior.
Remember: A local variable and a parameter sharing the same name does not mean they refer to the same object.</p>
</blockquote>
<h2 id="-move-zeroes">🖋️ Move Zeroes</h2>
<p>Given an integer array <code>nums</code>, move all <code>0</code>&rsquo;s to the end of it while maintaining the relative order of the non-zero elements.</p>
<p><strong>Note</strong> that you must do this in-place without making a copy of the array.</p>
<p><strong>Example 1:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Input: nums = [0,1,0,3,12]
</span></span><span class="line"><span class="cl">Output: [1,3,12,0,0]
</span></span></code></pre></div><hr>
<p>Here&rsquo;s an example of solving the &ldquo;Move Zeroes&rdquo; problem (a wrong one):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">moveZeroes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nums</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="mi">0</span> <span class="ow">in</span> <span class="n">nums</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">nums</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">counter</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="n">nums</span> <span class="o">=</span> <span class="n">nums</span> <span class="o">+</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="n">counter</span>
</span></span></code></pre></div><p>In this code, the final assignment to <code>nums</code> actually doesn’t affect the parameter <code>nums</code> because <strong>they are different variables</strong>.</p>
<p>Within the function, Python creates a new namespace, known as the <strong>local scope</strong>. All variables defined or assigned inside the function are, by default, considered local variables.</p>
<p>When you execute <code>nums = nums + [0] * counter</code> inside the function, Python’s interpreter assigns the new list object (from the right-hand expression) to the local variable <code>nums</code>. This means:</p>
<ul>
<li>The original <code>nums</code> (the parameter) still refers to the passed-in list object.</li>
<li>The local variable <code>nums</code> now refers to a <strong>new list object</strong>.</li>
<li><strong>The assignment <code>nums = ...</code></strong> changes the binding of the local <code>nums</code> to point to the new object, leaving the original passed-in list unaffected.</li>
</ul>
<p>A possible solution is to change the first <code>nums</code> to <code>nums[:]</code>, which means you are modifying the original object.</p>
<h4 id="two-pointer-solution">Two-pointer Solution:</h4>
<p>A more efficient approach to solving the &ldquo;Move Zeroes&rdquo; problem is using a two-pointer method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Solution</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">moveZeroes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nums</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">        Do not return anything, modify nums in-place instead.
</span></span></span><span class="line"><span class="cl"><span class="s2">        &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">left</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">right</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">nums</span><span class="p">)):</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">nums</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">nums</span><span class="p">[</span><span class="n">left</span><span class="p">],</span> <span class="n">nums</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">right</span><span class="p">],</span> <span class="n">nums</span><span class="p">[</span><span class="n">left</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">                <span class="n">left</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span></code></pre></div><p>In this solution, <code>left</code> is initialized to zero, and the first element being zero does not affect the algorithm&rsquo;s ability to move all zeros to the right. This two-pointer method efficiently processes the list in-place, making it a more optimal solution than the previous approach.</p>
]]></content:encoded></item><item><title>CO-STAR Template for ChatGPT</title><link>https://www.parkerchenca.com/tech/co-star-template-for-chatgpt/</link><pubDate>Thu, 10 Sep 2026 11:11:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/co-star-template-for-chatgpt/</guid><description>Getting ChatGPT to Do Exactly What You Need</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
If you use ChatGPT frequently, you&rsquo;ve probably encountered situations where it provides off-topic answers. Since we can&rsquo;t modify the model, the better approach is to rely on accurate prompts and additional context.</p>
</blockquote>
<h2 id="-main">🖋️ Main</h2>
<h4 id="let-chatgpt-answer-your-questions-accurately"><strong>Let ChatGPT Answer Your Questions Accurately!</strong></h4>
<p>First, you need to let ChatGPT know some personal information about you and how it should respond to you.</p>
<ol>
<li>Click on your profile picture at the top right corner.</li>
<li>Select &ldquo;Customize ChatGPT.&rdquo;</li>
<li>Hover over the &ldquo;Custom Instructions&rdquo; question mark on the right and fill in the information as guided.</li>
<li>Use the specific CO-STAR template in a new session.</li>
<li>Interact with ChatGPT.</li>
</ol>
<hr>
<h4 id="co-star-template">CO-STAR Template</h4>
<p>The CO-STAR template is a structured method that can help you communicate more clearly and effectively with ChatGPT. By providing context, objectives, style, tone, audience, and response format, you can explain exactly what you need from ChatGPT, and get replies that correspond more closely with your requirements.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># CO-STAR Template
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Template Example
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"># Context
</span></span><span class="line"><span class="cl"># I am a university student majoring in computer science, writing a paper on the application of machine learning in financial analysis.
</span></span><span class="line"><span class="cl"># Objective
</span></span><span class="line"><span class="cl"># Please help me write a section about the advantages and challenges of machine learning in stock market prediction.
</span></span><span class="line"><span class="cl"># Style
</span></span><span class="line"><span class="cl"># The style should be academic, using formal and technical language.
</span></span><span class="line"><span class="cl"># Tone
</span></span><span class="line"><span class="cl"># The tone should be serious and professional, avoiding humor or overly casual expressions.
</span></span><span class="line"><span class="cl"># Audience
</span></span><span class="line"><span class="cl"># The target audience is researchers and professionals in finance and computer science who are familiar with the relevant terminology and concepts.
</span></span><span class="line"><span class="cl"># Response
</span></span><span class="line"><span class="cl"># Please provide the content in paragraph form, including clear arguments and supporting evidence.
</span></span></code></pre></div><p>You can simply copy and paste this template to use it! Or, here is a more detailed explanation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">## Context
</span></span><span class="line"><span class="cl"># Provide relevant background information to help the model understand the current situation.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Objective
</span></span><span class="line"><span class="cl"># Clearly state your goal or the task you want ChatGPT to help you with.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Style
</span></span><span class="line"><span class="cl"># Specify the desired writing style, such as formal, informal, technical, etc.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Tone
</span></span><span class="line"><span class="cl"># Define the desired tone, such as persuasive, humorous, serious, etc.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Audience
</span></span><span class="line"><span class="cl"># Define the target audience so the model can adjust the complexity and terminology of its output.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Response
</span></span><span class="line"><span class="cl"># Specify the desired response format, such as a list, paragraph, or a specific data format.
</span></span></code></pre></div>]]></content:encoded></item><item><title>Tips for Better Google Searches</title><link>https://www.parkerchenca.com/tech/tips-for-better-google-searches/</link><pubDate>Thu, 10 Sep 2026 11:10:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/tips-for-better-google-searches/</guid><description>lmgtfy.(Let me google that for you)</description><content:encoded><![CDATA[<blockquote>
<p>💡 <strong>Prelude:</strong>
I collected some common advanced keywords for Google searching. These tips are generally applicable to most search engines.
You can also “search” on this page to find what you need.</p>
</blockquote>
<h3 id="exact-keywords">Exact Keywords</h3>
<p>Use <code>&quot;key words ...&quot;</code> (<strong>double quotes</strong>) to prevent keywords from being split up during the search.</p>
<hr>
<h3 id="exclude-keywords">Exclude Keywords</h3>
<p>Use <code>-</code> to exclude keywords.</p>
<p>For example:<code>python usage -w3s</code></p>
<hr>
<h3 id="wildcard">Wildcard</h3>
<p>The <code>*</code> in the search bar works similarly to the wildcard in Linux.</p>
<hr>
<h3 id="search-for-similar-words">Search for Similar Words</h3>
<p>Use the <code>~</code> symbol. For example, to search for words similar to &ldquo;elderly,&rdquo; input <code>~elderly</code>. This will return pages that include words like &ldquo;senior,&rdquo; &ldquo;older,&rdquo; &ldquo;aged,&rdquo; and more, in addition to &ldquo;elderly.&rdquo;</p>
<hr>
<h3 id="search-multiple-keywords">Search Multiple Keywords</h3>
<p>Use <code>|</code> to separate search terms.</p>
<p>You can also use <code>OR</code> and <code>AND</code> keywords. Make sure to use parentheses <code>()</code> to organize the structure of your search.</p>
<hr>
<h3 id="search-within-a-specific-website-site">Search Within a Specific Website: <code>site:</code></h3>
<p>Use <code>site:url (keywords)</code> before the search query.</p>
<p>You can use parentheses <code>()</code> around similar filters to better organize the search structure.</p>
<hr>
<h3 id="search-related-websites-related">Search Related Websites: <code>related:</code></h3>
<p>Using <code>related:</code> helps you find websites related to a specific site.</p>
<p>For example, searching for <code>&quot;related:runoob.com&quot;</code> will return all websites related to <code>runoob.com</code>.</p>
<hr>
<h3 id="time-range-daterange-after-before">Time Range: <code>daterange: AFTER: BEFORE</code></h3>
<p>Use <code>&quot;daterange:&quot;</code> to search for content within a specific time range. For example, searching for <code>&quot;marathon daterange:2011-01-01..2022-01-01&quot;</code> will return results related to marathons between 2011 and 2022.</p>
<p>Use <code>&quot;AFTER:2020&quot;</code> to get content after the year 2020, and so on.</p>
<hr>
<h3 id="search-for-keywords-in-titles-intitle">Search for Keywords in Titles: <code>intitle:</code></h3>
<p>Use <code>&quot;intitle:&quot;</code> to search for pages that have a certain keyword in the title tag. For example, searching for <code>&quot;intitle: Google&quot;</code> will return results with <code>Google</code> in the title.</p>
<hr>
<h3 id="specify-image-size-imagesize">Specify Image Size: <code>imagesize:</code></h3>
<p>Use syntax like <code>imagesize:500x500</code> to find images of a suitable size.</p>
<hr>
<h3 id="file-type-filetype">File Type: <code>filetype:</code></h3>
<p>Use <code>&quot;filetype:&quot;</code> to search for specific types of files. For example, searching for <code>&quot;Python manual filetype:pdf&quot;</code> will return all PDFs related to the Python manual.</p>
<hr>
<h3 id="find-cached-versions-of-web-pages">Find Cached Versions of Web Pages</h3>
<p>The <code>&quot;cache:&quot;</code> operator allows you to find cached versions of web pages. Google generates cached versions so users can access pages even when the website is down.</p>
<hr>
<h3 id="who-linked-to-this-image-src">Who Linked to This Image? <code>src:</code></h3>
<p>The <code>src:</code> search operator will return web pages that reference the image URL provided in the <code>src</code> attribute.</p>
]]></content:encoded></item><item><title>Choose your licenses</title><link>https://www.parkerchenca.com/tech/choose-your-licenses/</link><pubDate>Thu, 10 Sep 2026 11:09:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/choose-your-licenses/</guid><description>Common licenses in one table</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I sometimes wonder if adding a license to my campus homework is too serious.
Nevertheless, I still will add it.</p>
</blockquote>
<h2 id="-main">🖋️ Main</h2>
<table>
	<thead>
			<tr>
					<th>License</th>
					<th>Version</th>
					<th>Include License</th>
					<th>Include Source Code</th>
					<th>Trademark</th>
					<th>Status Change</th>
					<th>Commercial Use</th>
					<th>Distribution</th>
					<th>Modification</th>
					<th>Patent Right</th>
					<th>Private Use</th>
					<th>License Transfer</th>
					<th>No Liability</th>
					<th>No Trademark</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Apache License</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td><strong>FreeBSD License</strong></td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>2-Clause BSD License</td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>GNU General Public License(GPL)</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>GNU Lesser General Public License</td>
					<td>2.1</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>GNU General Public License</strong></td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>GNU Lesser General Public License</td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>MIT License</strong></td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td><strong>Mozilla Public License(MPL)</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>Eclipse Public License</td>
					<td>1.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>Affero General Public License</td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>General Copyright</td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>No</td>
					<td>Yes</td>
					<td>No</td>
					<td></td>
					<td></td>
			</tr>
	</tbody>
</table>
<h3 id="in-short">In short?</h3>
<ol>
<li><strong>Completely Open Source</strong> -&gt; MIT License, BSD License</li>
<li><strong>Open Source, But Must Credit the Original Author</strong> -&gt; Apache License 2.0</li>
<li><strong>Open Source, Must Use the Same License (Copyleft)</strong> -&gt; GPL</li>
<li><strong>Allows Commercial Use</strong> -&gt; MIT License, BSD License, Apache License 2.0, GPL</li>
<li><strong>Allows Closed Source (Can Be Integrated into Proprietary Software)</strong> -&gt; MIT License, BSD License, Apache License 2.0</li>
<li><strong>Does Not Allow Closed Source (Must Remain Open Source)</strong> -&gt; GPL</li>
</ol>
]]></content:encoded></item><item><title>My first post</title><link>https://www.parkerchenca.com/tech/my-first-post/</link><pubDate>Thu, 10 Sep 2026 11:08:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/my-first-post/</guid><description>This is my first post, which is also a template post</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Hi! This is my first post, which is also a template post.
Actually, this blog is built by Notion and Nextjs. I directly write my posts on Notion. So convenient!
You can check my references to have a see!</p>
</blockquote>
<h2 id="main">Main</h2>
<p>This is my main block.</p>
<h3 id="view-1">View 1</h3>
<blockquote>
<p>This is my citation.</p>
</blockquote>
<p>And view.</p>
<h2 id="summary">Summary</h2>
<p>This is my main summary. Sometimes I don&rsquo;t make a summary.</p>
<h2 id="-references">📎 <strong>References</strong></h2>
<ul>
<li>This is my references.</li>
<li><a href="https://github.com/tangly1024/NotionNext">https://github.com/tangly1024/NotionNext</a></li>
</ul>
]]></content:encoded></item><item><title>Building This Blog</title><link>https://www.parkerchenca.com/tech/building-this-blog/</link><pubDate>Wed, 09 Sep 2026 00:00:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/building-this-blog/</guid><description>Hugo, PaperMod, Algolia, and the four things that broke along the way.</description><content:encoded><![CDATA[<p>This site runs on Hugo with the PaperMod theme, bilingual content, and Algolia
for search. None of those choices were difficult. Wiring them together produced
four bugs that were, so this post is mostly about those.</p>
<h2 id="why-hugo">Why Hugo</h2>
<p>The decision came down to Hugo against Hexo. Two requirements settled it: content
organised by directory, and a tolerable path for Org-mode files.</p>
<p>Hugo maps <code>content/</code> directly onto URL structure. A file at
<code>content/tech/foo.md</code> becomes <code>/tech/foo/</code> and the <code>tech</code> directory becomes a
section with its own list page. No plugin, no configuration. Hexo can be pushed
into the same shape with <code>permalink</code> rules and a category plugin, but it is a
workaround rather than the design.</p>
<h2 id="the-org-mode-detour">The Org-mode detour</h2>
<p>Hugo ships Org support through go-org, so <code>.org</code> files render without a plugin.
That worked, briefly:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ERROR access denied: &#34;text/org&#34; is not whitelisted in policy &#34;security.allowContent&#34;
</span></span></code></pre></div><p>Hugo 0.166 denies <code>text/org</code> by default. The parser is present; the security
policy blocks it. Adding an override fixed it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">security</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">allowContent</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="s1">&#39;! ^text/html$&#39;</span><span class="w">
</span></span></span></code></pre></div><p>The override came back out later. Writing Org and exporting to Markdown with
ox-hugo keeps a single renderer in play, so Hugo only ever sees Markdown and the
security policy stays at its default. One less deviation from upstream.</p>
<h2 id="configuration-renames">Configuration renames</h2>
<p>Two config keys changed name in Hugo 0.158 and the older names still appear in
most tutorials:</p>
<table>
	<thead>
			<tr>
					<th>Old</th>
					<th>New</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>languageCode</code></td>
					<td><code>locale</code></td>
			</tr>
			<tr>
					<td><code>languages.&lt;lang&gt;.languageName</code></td>
					<td><code>languages.&lt;lang&gt;.label</code></td>
			</tr>
	</tbody>
</table>
<p>Both still work and both emit deprecation warnings. PaperMod&rsquo;s templates still
call <code>.Language.LanguageCode</code> internally, so the warnings appear even with a
fully modern config. They are the theme&rsquo;s, not yours.</p>
<h2 id="search">Search</h2>
<p>PaperMod bundles Fuse.js. It builds a JSON index at compile time, ships it to
the browser, and matches locally. Zero infrastructure, and for a small English
site it is the correct choice.</p>
<p>Two things pushed this site to Algolia instead. The whole index downloads on
every visit to the search page, which does not scale past a few hundred posts.
And Fuse does character-level fuzzy matching with no CJK tokenisation, which
matters for a site that is half Chinese.</p>
<p>There is no official Algolia integration for Hugo. The community packages —
<code>hugo-algolia</code>, <code>atomic-algolia</code> — stopped being maintained years ago and are
pinned to client v4 while current is v5. So: a template that emits records, a
search page built on InstantSearch, and a push script. Under 200 lines total,
all of it sitting on official libraries.</p>
<h3 id="the-escaping-bug">The escaping bug</h3>
<p>The search page passes configuration into JavaScript:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">cfg</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">{{</span><span class="w"> </span><span class="nx">dict</span><span class="w"> </span><span class="s">&#34;appId&#34;</span><span class="w"> </span><span class="err">$</span><span class="nx">appId</span><span class="w"> </span><span class="s">&#34;indexName&#34;</span><span class="w"> </span><span class="err">$</span><span class="nx">index</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">jsonify</span><span class="w"> </span><span class="p">}};</span><span class="w">
</span></span></span></code></pre></div><p>Go&rsquo;s <code>html/template</code> knows this is a JavaScript context and escapes the value
into a <em>string literal</em>. The result:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">cfg</span> <span class="o">=</span> <span class="s2">&#34;{\&#34;appId\&#34;:\&#34;...\&#34;,\&#34;indexName\&#34;:\&#34;blog_en\&#34;}&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p><code>cfg.indexName</code> is <code>undefined</code>. InstantSearch initialises against an undefined
index and the page renders an empty search box with no error. Wrapping the value
in <code>JSON.parse()</code> fixes it without reaching for <code>safeJS</code>, which would have
disabled the escaping that exists for good reason.</p>
<h3 id="the-truncate-bug">The truncate bug</h3>
<p>Records are truncated to stay under Algolia&rsquo;s 10KB limit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="p">.</span><span class="nx">Content</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">plainify</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">htmlUnescape</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">truncate</span><span class="w"> </span><span class="mi">2000</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="w">
</span></span></span></code></pre></div><p>Entities kept appearing in the index as <code>&amp;#34;</code>. Hugo&rsquo;s <code>truncate</code> is HTML-aware
and re-escapes on output, so it has to run <em>before</em> the unescaping, not after.</p>
<h3 id="the-leftover-fuse-bug">The leftover Fuse bug</h3>
<p>PaperMod injects its Fuse bundle conditionally:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="p">{{</span><span class="o">-</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">eq</span><span class="w"> </span><span class="p">.</span><span class="nx">Layout</span><span class="w"> </span><span class="s">`search`</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="p">}}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nx">link</span><span class="w"> </span><span class="nx">rel</span><span class="p">=</span><span class="s">&#34;preload&#34;</span><span class="w"> </span><span class="nx">as</span><span class="p">=</span><span class="s">&#34;fetch&#34;</span><span class="w"> </span><span class="nx">href</span><span class="p">=</span><span class="s">&#34;../index.json&#34;</span><span class="p">&gt;</span><span class="w">
</span></span></span></code></pre></div><p>The Algolia search page still declared <code>layout: &quot;search&quot;</code>, so the theme injected
15KB of Fuse and preloaded an <code>index.json</code> that no longer existed. Renaming the
layout to <code>algolia</code> sidesteps the condition entirely.</p>
<h2 id="what-is-left">What is left</h2>
<p>Comments are wired to giscus but switched off — the partial renders nothing
until a repository is configured. Analytics is a commented-out block waiting on
a GA4 property. Both are switches rather than commitments.</p>
<p>The remaining duplication is the Algolia index name, which appears in
<code>hugo.yaml</code> and again in the push script. Removing it would mean teaching the
script to parse YAML. Two constants do not justify a dependency.</p>
<h2 id="notes-to-self">Notes to self</h2>
<ul>
<li>Run <code>hugo server -e production</code> when checking SEO tags; the default
development environment omits OpenGraph, Twitter Cards, and JSON-LD entirely.</li>
<li>The index has to be pushed after every deploy. Fuse indexes travel with the
build; Algolia indexes live on someone else&rsquo;s server.</li>
<li>Test content needs to be long enough to scroll. The back-to-top button only
appears after a full viewport of scrolling, which a sixty-word post will never
trigger.</li>
</ul>
]]></content:encoded></item><item><title>Search</title><link>https://www.parkerchenca.com/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.parkerchenca.com/search/</guid><description>search</description></item></channel></rss>