<?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>Engineering on Mini Fish</title>
    <link>https://blog.minifish.org/categories/engineering/</link>
    <description>Recent content in Engineering on Mini Fish</description>
    <image>
      <title>Mini Fish</title>
      <url>https://blog.minifish.org/android-chrome-512x512.png</url>
      <link>https://blog.minifish.org/android-chrome-512x512.png</link>
    </image>
    <generator>Hugo -- 0.165.0</generator>
    <language>en-US</language>
    <copyright>Mini Fish 2014-present. Licensed under CC-BY-NC</copyright>
    <lastBuildDate>Sat, 15 Aug 2026 16:11:02 +0800</lastBuildDate>
    <atom:link href="https://blog.minifish.org/categories/engineering/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>driftloop: Browser Generative Music Without a Backend</title>
      <link>https://blog.minifish.org/posts/driftloop-browser-generative-music/</link>
      <pubDate>Thu, 11 Jun 2026 09:00:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/driftloop-browser-generative-music/</guid>
      <description>A project note on driftloop, a browser-based generative music app using algorithmic composition, FluidSynth in WebAssembly, and optional Magenta melody generation.</description>
      <content:encoded><![CDATA[<p>driftloop is a pure-frontend web app that streams continuous generative background music in the browser. Click play, and the music starts. Switch style buttons, and the arrangement morphs without a hard cut.</p>
<p>The important constraint is that every note is composed and synthesized live in the browser. There are no prerecorded loops, no server, no account, and no backend generation job.</p>
<h2 id="why-it-is-not-mainly-an-ai-app">Why it is not mainly an AI app</h2>
<p>The interesting origin story is that driftloop came after an earlier model-first attempt. That earlier direction tried to distill a multi-instrument music model and sample from it for the listening experience. The output was structurally chaotic in a way that sampling tweaks did not fix.</p>
<p>driftloop starts from a different premise: for continuous background music, structure matters more than model capacity.</p>
<p>Algorithmic composition handles the load-bearing parts:</p>
<ul>
<li>chord progression</li>
<li>voice leading</li>
<li>bass motion</li>
<li>rhythm</li>
<li>drum pattern</li>
<li>section shape</li>
</ul>
<p>A small model can still help with lead melody, but it should not be responsible for making the whole piece coherent.</p>
<h2 id="runtime-shape">Runtime shape</h2>
<p>The app has two layers:</p>
<ol>
<li>Vanilla JavaScript composition logic that keeps the music in key, on grid, and structurally coherent.</li>
<li>An optional MelodyRNN path through TensorFlow.js for lead melody.</li>
</ol>
<p>Synthesis uses <code>js-synthesizer</code>, a WebAssembly port of FluidSynth, with a General MIDI SoundFont through the WebAudio API.</p>
<p>The SoundFont is large, so deployment has a practical constraint: Cloudflare Pages has a single-file size limit smaller than the SoundFont. The app fetches the SoundFont from a public upstream mirror on first launch, then the service worker caches it for offline reuse.</p>
<h2 id="what-i-learned">What I learned</h2>
<p>Generative music is not only generation. It is arrangement, continuity, transitions, repetition management, and sound rendering.</p>
<p>The most important product question is not “is it AI?” It is “can I leave this playing without getting annoyed?” That favors simple, controllable structure over model novelty.</p>
<h2 id="current-status">Current status</h2>
<p>driftloop is private but product-shaped. It is a static PWA candidate, and the current architecture is intentionally deployable without backend secrets or runtime infrastructure.</p>
]]></content:encoded>
    </item>
    <item>
      <title>AeroPlay: A Flight-Mode Game Hub</title>
      <link>https://blog.minifish.org/posts/aeroplay-offline-game-hub/</link>
      <pubDate>Wed, 03 Jun 2026 09:00:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/aeroplay-offline-game-hub/</guid>
      <description>A project note on AeroPlay, a pure frontend offline game hub with mini games, localStorage progress, service worker caching, and add-to-home-screen support.</description>
      <content:encoded><![CDATA[<p>AeroPlay is a pure-frontend, mobile-first game hub optimized for flight-mode use. It includes small games like Snake, Tetris, 2048, Flappy Bird, Maze, Match-3, Sudoku, and Lights Out.</p>
<p>The whole point is that it should keep working with no network.</p>
<h2 id="why-build-it">Why build it</h2>
<p>Airplane mode is a useful product constraint. It removes a lot of lazy assumptions:</p>
<ul>
<li>no backend calls</li>
<li>no CDN dependency during play</li>
<li>no login</li>
<li>no remote save</li>
<li>no ads</li>
<li>no analytics requirement</li>
</ul>
<p>What remains is the app itself: local assets, local state, and games that are worth playing in short sessions.</p>
<h2 id="template-shape">Template shape</h2>
<p>AeroPlay is also designed as a template. The repo can be used to bootstrap another offline game hub without carrying old issues or unrelated history.</p>
<p>That makes the project more useful than a single app. It becomes a base pattern:</p>
<ul>
<li>Vite and TypeScript</li>
<li>local game modules</li>
<li>service worker</li>
<li>manifest</li>
<li><code>localStorage</code> progress</li>
<li>mobile-first layout</li>
</ul>
<h2 id="product-boundary">Product boundary</h2>
<p>The project should not become a general gaming platform. Its strength is the opposite: a small set of local games, predictable input, and no network requirement.</p>
<p>For this kind of app, “more features” can easily make the experience worse. If the user opens it in flight mode, the app should not show half-broken online features.</p>
<h2 id="what-i-learned">What I learned</h2>
<p>Offline-first is easiest when it is a requirement from the beginning. Retrofitting offline behavior onto an app that assumed servers and remote assets is much harder.</p>
<p>AeroPlay also shows that simple games still need polish:</p>
<ul>
<li>touch controls</li>
<li>stable layout</li>
<li>saved state</li>
<li>fast startup</li>
<li>no accidental scroll</li>
<li>clear pause and restart behavior</li>
</ul>
<p>Those details matter more on a phone than in a desktop demo.</p>
<h2 id="open-source-status">Open source status</h2>
<p>AeroPlay is public because it is self-contained, harmless to share, and useful as a template. It is a good example of a small project whose constraints make it more reusable.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bedrock Lab: A Behavior Pack as a Small Rules Sandbox</title>
      <link>https://blog.minifish.org/posts/bedrock-lab-behavior-pack/</link>
      <pubDate>Tue, 02 Jun 2026 09:00:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/bedrock-lab-behavior-pack/</guid>
      <description>A project note on Bedrock Lab, a Minecraft Bedrock behavior pack with sprint regeneration, random effects, custom drops, and fishing loot changes.</description>
      <content:encoded><![CDATA[<p>Bedrock Lab is a behavior-only sandbox for Minecraft Bedrock Edition. It packages small gameplay rule experiments into a behavior pack that can be imported and activated without experimental toggles.</p>
<p>The project is not meant to be a large mod. It is a rules sandbox.</p>
<h2 id="what-it-changes">What it changes</h2>
<p>The pack includes features such as:</p>
<ul>
<li>sprint regeneration</li>
<li>random player effects</li>
<li>torch drops on non-player entity death</li>
<li>local snow effect on player death</li>
<li>random material drops from broken blocks</li>
<li>adjusted fishing loot weights</li>
</ul>
<p>These are intentionally playful mechanics. The point is to test how small rule changes affect the feel of a world.</p>
<h2 id="why-behavior-only-matters">Why behavior-only matters</h2>
<p>Keeping the pack behavior-only lowers the setup cost. There is no custom client asset pipeline and no experimental toggle requirement.</p>
<p>That makes it easier to share across devices:</p>
<ul>
<li>package as <code>.mcpack</code></li>
<li>import on iOS or Windows</li>
<li>activate in world settings</li>
<li>play immediately</li>
</ul>
<p>For a small personal pack, install friction matters more than architectural elegance.</p>
<h2 id="the-design-lesson">The design lesson</h2>
<p>Game modding is a good reminder that systems can be fun without being complicated. A simple rule like “breaking blocks produces random materials” changes the entire resource economy.</p>
<p>The engineering lesson is to make each rule easy to remove. If a mechanic stops being fun, it should not be tangled with the rest of the pack.</p>
<h2 id="what-i-learned">What I learned</h2>
<p>Small game experiments should be packaged early. A mechanic that only works in a local development folder is not really tested. It needs to be imported, activated, and played in the actual environment.</p>
<p>Bedrock Lab&rsquo;s value is that it turns ideas into a package quickly. That makes it easier to decide whether a mechanic is worth keeping.</p>
<h2 id="current-status">Current status</h2>
<p>Bedrock Lab is private and small. It is the kind of project that is more useful as a personal sandbox than as a maintained public mod.</p>
]]></content:encoded>
    </item>
    <item>
      <title>cta-guard: Risk Controls Before Trading Logic</title>
      <link>https://blog.minifish.org/posts/cta-guard-trading-risk-system/</link>
      <pubDate>Sun, 31 May 2026 09:00:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/cta-guard-trading-risk-system/</guid>
      <description>A sanitized project note on cta-guard, a Rust trading runtime and research tool focused on risk controls, ingestion, backtesting, and operational guardrails.</description>
      <content:encoded><![CDATA[<p><code>cta-guard</code> is a private trading-system project. It includes a runtime loop, ingestion tools, backtesting, walk-forward validation, health checks, and venue integration.</p>
<p>This is the kind of project where the most useful public topic is not the trading strategy. It is the guardrail design.</p>
<h2 id="why-risk-first">Why risk first</h2>
<p>Trading code has a dangerous failure mode: a bug can become a position.</p>
<p>That changes the engineering priority. Before clever strategy logic, the system needs operational controls:</p>
<ul>
<li>dry-run mode</li>
<li>explicit venue adapters</li>
<li>heartbeat checks</li>
<li>halted state</li>
<li>read-only mode</li>
<li>data freshness checks</li>
<li>position and exposure constraints</li>
<li>clear separation between research and live execution</li>
</ul>
<p>The project name reflects that priority. The guard matters before the CTA.</p>
<h2 id="system-shape">System shape</h2>
<p>The maintained path is a modular trader stack:</p>
<ul>
<li>runtime orchestration</li>
<li>risk app service</li>
<li>strategy app service</li>
<li>backtest app service</li>
<li>domain models and ports</li>
<li>SQLite repositories</li>
<li>venue adapters and stubs</li>
</ul>
<p>There are separate binaries for live or dry-run runtime, health checks, ingestion, historical import, backtest, and walk-forward validation.</p>
<p>That separation is important. A backtest binary should not have the same operational authority as a live execution process.</p>
<h2 id="what-should-stay-private">What should stay private</h2>
<p>Some details are not appropriate for a public blog:</p>
<ul>
<li>strategy parameters</li>
<li>production configuration</li>
<li>account or venue details</li>
<li>exact deployment topology</li>
<li>operational thresholds</li>
<li>anything that could imply a trade recommendation</li>
</ul>
<p>The safe public layer is architecture: how to keep execution constrained, observable, and stoppable.</p>
<h2 id="what-i-learned">What I learned</h2>
<p>Risk control is not one module. It is a state machine that should shape the whole runtime.</p>
<p>A good trading system needs to answer boring questions quickly:</p>
<ul>
<li>is data fresh?</li>
<li>is the venue reachable?</li>
<li>is the runtime allowed to trade?</li>
<li>what happens after an error?</li>
<li>can the system stop without making things worse?</li>
<li>can research code accidentally reach execution?</li>
</ul>
<p>If those answers are unclear, the system is not ready for live use.</p>
<h2 id="current-status">Current status</h2>
<p><code>cta-guard</code> is private. I may continue writing about its engineering lessons, but only at the level of risk design, runtime isolation, and validation workflow.</p>
]]></content:encoded>
    </item>
    <item>
      <title>TapSurge: An iPad Tap-Speed Tool Built for Competition Use</title>
      <link>https://blog.minifish.org/posts/tapsurge-ipad-tap-test/</link>
      <pubDate>Sun, 24 May 2026 08:20:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/tapsurge-ipad-tap-test/</guid>
      <description>A project note on TapSurge, a Vite and TypeScript tap-speed competition tool designed for iPad, offline use, and raw timestamp export.</description>
      <content:encoded><![CDATA[<p>TapSurge is an offline-first multi-finger click-speed test for iPad competition use. It is built with Vite, TypeScript, native DOM APIs, and Canvas.</p>
<p>The product sounds tiny: count taps for 10, 30, or 60 seconds. The interesting part is making that count credible.</p>
<h2 id="why-a-custom-tool">Why a custom tool</h2>
<p>Most tap-speed apps are built for casual play. Competition use has different requirements:</p>
<ul>
<li>work offline</li>
<li>run well on an iPad</li>
<li>avoid accidental browser gestures</li>
<li>count multi-finger input correctly</li>
<li>preserve enough raw data to audit a run</li>
<li>keep history locally without accounts</li>
</ul>
<p>For this use case, simplicity matters more than visual novelty.</p>
<h2 id="input-model">Input model</h2>
<p>TapSurge uses <code>pointerdown</code> and active pointer tracking. The key rule is that holding a finger down should not count repeatedly. A tap is a new press, not a frame, animation event, or repeated touch state.</p>
<p>The app records:</p>
<ul>
<li>total taps</li>
<li>average CPS</li>
<li>one-second live CPS</li>
<li>maximum live CPS</li>
<li>maximum simultaneous fingers</li>
<li>raw timestamps and pointer IDs</li>
</ul>
<p>That raw data is important. It lets a run be inspected after the fact instead of trusting only the final number.</p>
<h2 id="offline-design">Offline design</h2>
<p>The app is intended to work in a PWA-like mode. It has a local app shell, a service worker, and no backend dependency during play.</p>
<p>This is one of those projects where offline support is not a nice extra. It is part of the user story. If the tool is used at a booth, in a classroom, or during a small event, network dependency is unnecessary risk.</p>
<h2 id="ui-constraints">UI constraints</h2>
<p>The UI has to be obvious under pressure. A player should not be reading instructions while the timer is running.</p>
<p>The controls are intentionally few:</p>
<ul>
<li>choose duration</li>
<li>start</li>
<li>tap</li>
<li>see result</li>
<li>review history</li>
<li>export evidence if needed</li>
</ul>
<p>The harder work is preventing the browser from interfering: double-tap zoom, scroll gestures, safe-area issues, and fullscreen behavior all matter more on a real iPad than in a desktop browser.</p>
<h2 id="what-i-learned">What I learned</h2>
<p>Small event tools benefit from being boring. The best version is not the most animated one; it is the one that produces trustworthy results with minimal setup.</p>
<p>TapSurge is a good example of a private tool that could be public, but does not need a large roadmap. Its scope is the feature.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Minifish Lab Projects</title>
      <link>https://blog.minifish.org/posts/minifish-lab-projects/</link>
      <pubDate>Sun, 24 May 2026 08:00:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/minifish-lab-projects/</guid>
      <description>A living index of Minifish Lab projects, with short notes on what each project does, its current status, and the project notes in this series.</description>
      <content:encoded><![CDATA[<p>This is a living index of the projects I keep under Minifish Lab. Some of them are public. Some are private because they contain personal operations, deployment assumptions, trading workflow details, or code that is useful to me but not ready to be maintained for other people.</p>
<p>The goal of this series is not to pretend every small repository should become a product. The goal is to leave a useful engineering record: why each project exists, what design choices mattered, what I learned from it, and where the boundary is between a good private tool and a project worth publishing.</p>
<p>I will keep this page updated as projects change.</p>
<h2 id="project-map">Project map</h2>
<table>
	<thead>
			<tr>
					<th>Project</th>
					<th>Area</th>
					<th>Source</th>
					<th>Status</th>
					<th>Project note</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>PocketBabel</code></td>
					<td>AI / Browser app</td>
					<td>Public</td>
					<td>Active</td>
					<td><a href="/posts/pocketbabel-browser-translation/">PocketBabel: Browser Translation Without a Backend</a></td>
			</tr>
			<tr>
					<td><code>tailgate</code></td>
					<td>AI infrastructure</td>
					<td>Private</td>
					<td>Active</td>
					<td><a href="/posts/tailgate-private-ai-gateway/">Tailgate: A Private AI Gateway for Local and Remote Models</a></td>
			</tr>
			<tr>
					<td><code>qwen-local</code></td>
					<td>Local AI</td>
					<td>Private</td>
					<td>Active</td>
					<td><a href="/posts/qwen-local-on-apple-silicon/">qwen-local: Running an OpenAI-Compatible Model Service on Apple Silicon</a></td>
			</tr>
			<tr>
					<td><code>tapsurge</code></td>
					<td>Offline frontend tool</td>
					<td>Private</td>
					<td>Active</td>
					<td><a href="/posts/tapsurge-ipad-tap-test/">TapSurge: An iPad Tap-Speed Tool Built for Competition Use</a></td>
			</tr>
			<tr>
					<td><code>ob-sizer</code></td>
					<td>Database tooling</td>
					<td>Private</td>
					<td>Active</td>
					<td><a href="/posts/ob-sizer-capacity-estimator/">OB Sizer: Turning Migration Sizing into a Browser Tool</a></td>
			</tr>
			<tr>
					<td><a href="https://github.com/minifish-org/agentd"><code>agentd</code></a></td>
					<td>Agent runtime</td>
					<td>Public</td>
					<td>Experimental alpha</td>
					<td><a href="/posts/agentd-transport-neutral-runtime/">agentd: A Transport-Neutral Runtime for Personal Agents</a></td>
			</tr>
			<tr>
					<td><code>canopy</code></td>
					<td>Maps / MCP</td>
					<td>Private</td>
					<td>Active</td>
					<td>Scheduled: 2026-06-09</td>
			</tr>
			<tr>
					<td><code>nightfall</code></td>
					<td>AI game</td>
					<td>Private</td>
					<td>Prototype</td>
					<td>Scheduled: 2026-06-10</td>
			</tr>
			<tr>
					<td><code>driftloop</code></td>
					<td>Generative music</td>
					<td>Private</td>
					<td>Active prototype</td>
					<td>Scheduled: 2026-06-11</td>
			</tr>
			<tr>
					<td><code>mood-midi-mlx</code></td>
					<td>Local AI / Music</td>
					<td>Private</td>
					<td>Research prototype</td>
					<td>Scheduled: 2026-06-12</td>
			</tr>
			<tr>
					<td><code>tegdb</code></td>
					<td>Database</td>
					<td>Public</td>
					<td>Experimental</td>
					<td><a href="/posts/tegdb-embedded-database/">TegDB: Notes from Building a Small Embedded Database</a></td>
			</tr>
			<tr>
					<td><code>ob-skills</code></td>
					<td>AI workflow / Database</td>
					<td>Public</td>
					<td>Active</td>
					<td><a href="/posts/ob-skills-oceanbase-agent-skills/">ob-skills: Packaging OceanBase Knowledge as Agent Skills</a></td>
			</tr>
			<tr>
					<td><code>quacklake</code></td>
					<td>Analytics</td>
					<td>Private</td>
					<td>Prototype</td>
					<td><a href="/posts/quacklake-wasm-analytics-prototype/">QuackLake: A DuckDB-WASM Analytics Prototype</a></td>
			</tr>
			<tr>
					<td><code>scale-kv</code></td>
					<td>Storage systems</td>
					<td>Private</td>
					<td>Experimental</td>
					<td><a href="/posts/scale-kv-storage-experiment/">scale-kv: A Storage Experiment About Complexity</a></td>
			</tr>
			<tr>
					<td><code>cta-guard</code></td>
					<td>Trading systems</td>
					<td>Private</td>
					<td>Sensitive</td>
					<td><a href="/posts/cta-guard-trading-risk-system/">cta-guard: Risk Controls Before Trading Logic</a></td>
			</tr>
			<tr>
					<td><code>tegdb-server</code></td>
					<td>Database server</td>
					<td>Public</td>
					<td>Experimental</td>
					<td><a href="/posts/tegdb-server-postgres-compatible/">tegdb-server: Putting a PostgreSQL-Compatible Protocol in Front of TegDB</a></td>
			</tr>
			<tr>
					<td><code>bedrock-lab</code></td>
					<td>Game modding</td>
					<td>Private</td>
					<td>Small tool</td>
					<td><a href="/posts/bedrock-lab-behavior-pack/">Bedrock Lab: A Behavior Pack as a Small Rules Sandbox</a></td>
			</tr>
			<tr>
					<td><code>aeroplay</code></td>
					<td>Offline games</td>
					<td>Public</td>
					<td>Template-ready</td>
					<td><a href="/posts/aeroplay-offline-game-hub/">AeroPlay: A Flight-Mode Game Hub</a></td>
			</tr>
			<tr>
					<td><code>map-ask</code></td>
					<td>Maps / AI</td>
					<td>Private</td>
					<td>Prototype</td>
					<td><a href="/posts/map-ask-natural-language-geosearch/">map-ask: Natural-Language Geospatial Search</a></td>
			</tr>
			<tr>
					<td><code>good-fishing-day</code></td>
					<td>Personal dashboard</td>
					<td>Private</td>
					<td>Personal utility</td>
					<td><a href="/posts/good-fishing-day-dashboard/">good-fishing-day: A Fishing Weather Dashboard</a></td>
			</tr>
			<tr>
					<td><code>distilmuse</code></td>
					<td>Music AI</td>
					<td>Private</td>
					<td>Remote placeholder</td>
					<td>No project note yet</td>
			</tr>
			<tr>
					<td><code>symbolic-math-mlx</code></td>
					<td>Local AI / Math</td>
					<td>Private</td>
					<td>Remote placeholder</td>
					<td>No project note yet</td>
			</tr>
	</tbody>
</table>
<h2 id="why-write-about-private-projects">Why write about private projects?</h2>
<p>Open source is not the only useful form of sharing. A private project can still contain lessons worth publishing:</p>
<ul>
<li>how the problem was framed</li>
<li>which constraints shaped the architecture</li>
<li>what was deliberately left out</li>
<li>where a prototype became too complex</li>
<li>what I would do differently next time</li>
</ul>
<p>For private repositories, these notes avoid secrets, private network details, exact production configuration, personal data, and sensitive business or trading parameters. The public artifact is the engineering story, not a dump of implementation details.</p>
<h2 id="how-i-classify-these-projects">How I classify these projects</h2>
<p>Some projects are small tools that should stay small. <code>tapsurge</code>, <code>good-fishing-day</code>, and <code>bedrock-lab</code> are in that category. Their value comes from being built for one specific situation.</p>
<p>Some are experiments in system shape. <code>agentd</code>, <code>scale-kv</code>, <code>quacklake</code>, <code>tegdb</code>, and <code>tegdb-server</code> are more about understanding boundaries than shipping a polished product.</p>
<p>Some are workbench infrastructure. <code>qwen-local</code>, <code>tailgate</code>, <code>PocketBabel</code>, <code>canopy</code>, and <code>ob-skills</code> exist because I want AI tools to fit into my own environment instead of depending entirely on remote services.</p>
<p>Some are creative-system prototypes. <code>driftloop</code>, <code>mood-midi-mlx</code>, and <code>nightfall</code> are less about CRUD-product shape and more about how rules, local models, and browser runtimes can create a coherent experience.</p>
<p>Some projects sit close to professional or sensitive domains. <code>ob-sizer</code> is safe to discuss at the methodology level. <code>cta-guard</code> needs more caution: the interesting public topic is risk control and operational design, not trading edge.</p>
<h2 id="maintenance-rule">Maintenance rule</h2>
<p>When a project changes meaningfully, I will update this index first. If the change is only implementation detail, the individual post can stay as a snapshot. If the project changes direction, graduates into a product, or gets retired, the index should say so plainly.</p>
<p>That makes this page the map, and each project post a field note.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The Correct Way to Use `go build`</title>
      <link>https://blog.minifish.org/posts/the-correct-way-to-use-go-build/</link>
      <pubDate>Thu, 28 Nov 2024 15:41:19 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/the-correct-way-to-use-go-build/</guid>
      <description>When working with Go, it&amp;#39;s important to know the proper way to compile your programs to avoid common errors. Here are some tips on using the go build command effectively.</description>
      <content:encoded><![CDATA[<p>When working with Go, it&rsquo;s important to know the proper way to compile your programs to avoid common errors. Here are some tips on using the <code>go build</code> command effectively.</p>
<h2 id="recommended-usage">Recommended Usage</h2>
<ul>
<li>
<p><strong>Compile all Go files in the current directory:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go build
</span></span></code></pre></div></li>
<li>
<p><strong>Compile all Go files explicitly:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go build *.go
</span></span></code></pre></div></li>
</ul>
<h2 id="common-pitfalls">Common Pitfalls</h2>
<h3 id="compiling-a-single-file">Compiling a Single File</h3>
<p>Running:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go build main.go
</span></span></code></pre></div><p>will only build <code>main.go</code>. This can lead to errors if <code>main.go</code> depends on other Go files in the same package, as those files won&rsquo;t be included in the build process.</p>
<h3 id="including-non-go-files">Including Non-Go Files</h3>
<p>Using:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go build *
</span></span></code></pre></div><p>will cause an error if the <code>*</code> wildcard includes non-Go files. The compiler will output an error message stating that only Go files can be compiled. This serves as a precise reminder to exclude non-Go files from the build command.</p>
<hr>
<p>By using <code>go build</code> correctly, you can ensure that all necessary files in your package are compiled together, avoiding missing dependencies and other common compilation issues.</p>
]]></content:encoded>
    </item>
    <item>
      <title>How to Configure a Chinese LaTeX Environment on Windows</title>
      <link>https://blog.minifish.org/posts/how-to-configure-a-chinese-latex-environment-on-windows/</link>
      <pubDate>Wed, 31 Mar 2021 00:00:00 +0000</pubDate>
      <guid>https://blog.minifish.org/posts/how-to-configure-a-chinese-latex-environment-on-windows/</guid>
      <description>Initially, I didn&amp;#39;t think this was something worth writing about, because CTex was previously working smoothly for everyone. However, it turns out that CTex hasn&amp;#39;t been updated...</description>
      <content:encoded><![CDATA[<h2 id="background">Background</h2>
<p>Initially, I didn&rsquo;t think this was something worth writing about, because CTex was previously working smoothly for everyone. However, it turns out that CTex hasn&rsquo;t been updated since 2016. So, I wanted to find a replacement for Chinese LaTeX on Windows in 2021.</p>
<h2 id="configuration-method">Configuration Method</h2>
<ol>
<li>Install MiKTeX (TexLive should work as well). MiKTeX can automatically download dependency packages and you can also proactively install the ctex package.</li>
<li>Install the VSCode LaTeX extension.</li>
<li>Configure the LaTeX extension. I found a powerful configuration on Zhihu, but it’s quite complex, so I simplified it a bit.</li>
</ol>
<p>A brief explanation: the core components here are the recipes and tools. Tools are the compilation toolchain, specifying which tools to use for compilation and the options to use, without regard to order. Recipes define how to combine the above tools to generate the final document, where the order does matter. I&rsquo;ve put XeLaTex first here because it&rsquo;s the most compatible for compiling Chinese. If you use pdflatex to compile Chinese documents, you&rsquo;re likely to encounter issues.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;latex-workshop.latex.recipes&#34;</span>: [
</span></span><span style="display:flex;"><span>         {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;XeLaTeX&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;xelatex&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;latexmk 🔃&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;latexmk&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;latexmk (latexmkrc)&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;latexmk_rconly&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;latexmk (lualatex)&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;lualatexmk&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;pdflatex ➞ bibtex ➞ pdflatex × 2&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;pdflatex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;bibtex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;pdflatex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;pdflatex&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Compile Rnw files&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;rnw2tex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;latexmk&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;Compile Jnw files&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;jnw2tex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;latexmk&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;tectonic&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tools&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;tectonic&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;latex-workshop.latex.tools&#34;</span>: [
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;xelatex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;xelatex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-synctex=1&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-interaction=nonstopmode&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-file-line-error&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOCFILE%&#34;</span>
</span></span><span style="display:flex;"><span>            ]
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;latexmk&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;latexmk&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-synctex=1&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-interaction=nonstopmode&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-file-line-error&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-pdf&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-outdir=%OUTDIR%&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOC%&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;lualatexmk&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;latexmk&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-synctex=1&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-interaction=nonstopmode&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-file-line-error&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-lualatex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-outdir=%OUTDIR%&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOC%&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;latexmk_rconly&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;latexmk&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOC%&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;pdflatex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;pdflatex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-synctex=1&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-interaction=nonstopmode&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-file-line-error&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOC%&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;bibtex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;bibtex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOCFILE%&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;rnw2tex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;Rscript&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-e&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;knitr::opts_knit$set(concordance = TRUE); knitr::knit(&#39;%DOCFILE_EXT%&#39;)&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;jnw2tex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;julia&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-e&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;using Weave; weave(\&#34;%DOC_EXT%\&#34;, doctype=\&#34;tex\&#34;)&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;jnw2texmintex&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;julia&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;-e&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;using Weave; weave(\&#34;%DOC_EXT%\&#34;, doctype=\&#34;texminted\&#34;)&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;tectonic&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;tectonic&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;--synctex&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;--keep-logs&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;%DOC%.tex&#34;</span>
</span></span><span style="display:flex;"><span>            ],
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;env&#34;</span>: {}
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;latex-workshop.view.pdf.viewer&#34;</span>: <span style="color:#e6db74">&#34;tab&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ol>
<li>Create a folder.</li>
<li>Use VSCode to open this folder and create a .tex file with the following content:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-tex" data-lang="tex"><span style="display:flex;"><span><span style="color:#66d9ef">\documentclass</span><span style="color:#a6e22e">[UTF8]</span>{ctexart}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\begin</span>{document}
</span></span><span style="display:flex;"><span>OK, it’s all set...
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">\end</span>{document}
</span></span></code></pre></div><p>It should automatically start compiling. Confirm to download any required dependencies if prompted. The compiled effect is as follows:</p>
<p><img alt="test" loading="lazy" src="/posts/how-to-configure-a-chinese-latex-environment-on-windows/20210331113405.webp"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Using delve to Debug Golang Programs</title>
      <link>https://blog.minifish.org/posts/using-delve-to-debug-golang-programs/</link>
      <pubDate>Mon, 16 Sep 2019 13:24:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/using-delve-to-debug-golang-programs/</guid>
      <description>When I first started writing Golang, I was always looking for a convenient debugging tool. Back then, I came across documentation about using gdb to debug and also tried delve,...</description>
      <content:encoded><![CDATA[<h2 id="background">Background</h2>
<p>When I first started writing Golang, I was always looking for a convenient debugging tool. Back then, I came across documentation about using <code>gdb</code> to debug and also tried <code>delve</code>, but neither felt easy to use. Later, on someone&rsquo;s advice, I went back to the good old <code>print</code> statements&hellip;</p>
<p>Over the past couple of days, I was debugging <code>go test</code> and found that tests would always hang when run per package. I couldn&rsquo;t think of a suitable method at first, so I thought of <code>delve</code> again. After giving it a try, I found it has become much more mature than before.</p>
<h2 id="usage">Usage</h2>
<p><code>dlv attach ${pid}</code> is the method I use most often. After attaching, you can use debugging commands similar to <code>gdb</code>. You can use <code>help</code> to view specific commands.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>(dlv) help
</span></span><span style="display:flex;"><span>The following commands are available:
</span></span><span style="display:flex;"><span>    args ------------------------ Print function arguments.
</span></span><span style="display:flex;"><span>    break (alias: b) ------------ Sets a breakpoint.
</span></span><span style="display:flex;"><span>    breakpoints (alias: bp) ----- Print out info for active breakpoints.
</span></span><span style="display:flex;"><span>    call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
</span></span><span style="display:flex;"><span>    clear ----------------------- Deletes breakpoint.
</span></span><span style="display:flex;"><span>    clearall -------------------- Deletes multiple breakpoints.
</span></span><span style="display:flex;"><span>    condition (alias: cond) ----- Set breakpoint condition.
</span></span><span style="display:flex;"><span>    config ---------------------- Changes configuration parameters.
</span></span><span style="display:flex;"><span>    continue (alias: c) --------- Run until breakpoint or program termination.
</span></span><span style="display:flex;"><span>    deferred -------------------- Executes command in the context of a deferred call.
</span></span><span style="display:flex;"><span>    disassemble (alias: disass) - Disassembler.
</span></span><span style="display:flex;"><span>    down ------------------------ Move the current frame down.
</span></span><span style="display:flex;"><span>    edit (alias: ed) ------------ Open where you are in $DELVE_EDITOR or $EDITOR
</span></span><span style="display:flex;"><span>    exit (alias: quit | q) ------ Exit the debugger.
</span></span><span style="display:flex;"><span>    frame ----------------------- Set the current frame, or execute command on a different frame.
</span></span><span style="display:flex;"><span>    funcs ----------------------- Print list of functions.
</span></span><span style="display:flex;"><span>    goroutine (alias: gr) ------- Shows or changes current goroutine.
</span></span><span style="display:flex;"><span>    goroutines (alias: grs) ----- List program goroutines.
</span></span><span style="display:flex;"><span>    help (alias: h) ------------- Prints the help message.
</span></span><span style="display:flex;"><span>    libraries ------------------- List loaded dynamic libraries.
</span></span><span style="display:flex;"><span>    list (alias: ls | l) -------- Show source code.
</span></span><span style="display:flex;"><span>    locals ---------------------- Print local variables.
</span></span><span style="display:flex;"><span>    next (alias: n) ------------- Step over to next source line.
</span></span><span style="display:flex;"><span>    on -------------------------- Executes a command when a breakpoint is hit.
</span></span><span style="display:flex;"><span>    print (alias: p) ------------ Evaluate an expression.
</span></span><span style="display:flex;"><span>    regs ------------------------ Print contents of CPU registers.
</span></span><span style="display:flex;"><span>    restart (alias: r) ---------- Restart process.
</span></span><span style="display:flex;"><span>    set ------------------------- Changes the value of a variable.
</span></span><span style="display:flex;"><span>    source ---------------------- Executes a file containing a list of delve commands.
</span></span><span style="display:flex;"><span>    sources --------------------- Print list of source files.
</span></span><span style="display:flex;"><span>    stack (alias: bt) ----------- Print stack trace.
</span></span><span style="display:flex;"><span>    step (alias: s) ------------- Single step through program.
</span></span><span style="display:flex;"><span>    step-instruction (alias: si)  Single step a single CPU instruction.
</span></span><span style="display:flex;"><span>    stepout (alias: so) --------- Step out of the current function.
</span></span><span style="display:flex;"><span>    thread (alias: tr) ---------- Switch to the specified thread.
</span></span><span style="display:flex;"><span>    threads --------------------- Print out info for every traced thread.
</span></span><span style="display:flex;"><span>    trace (alias: t) ------------ Set tracepoint.
</span></span><span style="display:flex;"><span>    types ----------------------- Print list of types.
</span></span><span style="display:flex;"><span>    up -------------------------- Move the current frame up.
</span></span><span style="display:flex;"><span>    vars ------------------------ Print package variables.
</span></span><span style="display:flex;"><span>    whatis ---------------------- Prints type of an expression.
</span></span><span style="display:flex;"><span>Type help followed by a command for full documentation.
</span></span></code></pre></div><p>Many of these commands are the same as those in <code>gdb</code>. Another command I use frequently is <code>grs</code>, which outputs all goroutines. You can also use <code>grs -t</code>, which is equivalent to <code>gdb</code>&rsquo;s <code>t a a bt</code>. The only slight drawback is that it only outputs 10 stack frames, and any additional ones are truncated.</p>
<p>Additionally, it seems that processes forked by <code>go test</code> can&rsquo;t be attached to. If you want to test, you must first compile it into a test file and then execute it. You can refer to <a href="https://github.com/pingcap/tidb/issues/12184">this issue</a> for more details.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>$ dlv attach 19654
</span></span><span style="display:flex;"><span>could not attach to pid 19654: decoding dwarf section info at offset 0x0: too short
</span></span></code></pre></div><p>Furthermore, by default, Go&rsquo;s <code>test</code> caches results, which can be controlled via environment variables. However, with Go modules (<code>go mod</code>), it&rsquo;s recommended to use <code>./ddl.test -test.count=1</code> to disable caching. It doesn&rsquo;t feel very elegant.</p>
]]></content:encoded>
    </item>
    <item>
      <title>How Immediate is Golang&#39;s Panic</title>
      <link>https://blog.minifish.org/posts/how-immediate-is-golangs-panic/</link>
      <pubDate>Thu, 26 Jul 2018 14:24:00 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/how-immediate-is-golangs-panic/</guid>
      <description>Let&amp;#39;s first look at the following code snippet:</description>
      <content:encoded><![CDATA[<p>Let&rsquo;s first look at the following code snippet:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-golang" data-lang="golang"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;os&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;runtime&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;time&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">runtime</span>.<span style="color:#a6e22e">GOMAXPROCS</span>(<span style="color:#ae81ff">2</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">a</span> <span style="color:#f92672">:=</span> make(<span style="color:#66d9ef">map</span>[<span style="color:#66d9ef">int</span>]<span style="color:#66d9ef">int</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">go</span> <span style="color:#66d9ef">func</span>() {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">a</span>[<span style="color:#ae81ff">1</span>] = <span style="color:#a6e22e">i</span>
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">i</span><span style="color:#f92672">++</span>
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">time</span>.<span style="color:#a6e22e">Sleep</span>(<span style="color:#ae81ff">1000</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}()
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">a</span>[<span style="color:#ae81ff">1</span>] &gt; <span style="color:#ae81ff">1000000</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">a</span>[<span style="color:#ae81ff">1</span>])
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Exit</span>(<span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>After compiling and running it (assuming your machine has 2 or more cores), you will get the following error:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>fatal error: concurrent map read and map write
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>goroutine 1 [running]:
</span></span><span style="display:flex;"><span>runtime.throw(0x10c3e05, 0x21)
</span></span><span style="display:flex;"><span>        /usr/local/Cellar/go/1.10.3/libexec/src/runtime/panic.go:616 +0x81 fp=0xc42004bf00 sp=0xc42004bee0 pc=0x10263f1
</span></span><span style="display:flex;"><span>runtime.mapaccess1_fast64(0x10a5b60, 0xc42007e180, 0x1, 0xc42008e048)
</span></span><span style="display:flex;"><span>        /usr/local/Cellar/go/1.10.3/libexec/src/runtime/hashmap_fast.go:101 +0x197 fp=0xc42004bf28 sp=0xc42004bf00 pc=0x1008d27
</span></span><span style="display:flex;"><span>main.main()
</span></span><span style="display:flex;"><span>        /Users/yusp/test/panic3/main.go:22 +0x7c fp=0xc42004bf88 sp=0xc42004bf28 pc=0x108e28c
</span></span><span style="display:flex;"><span>runtime.main()
</span></span><span style="display:flex;"><span>        /usr/local/Cellar/go/1.10.3/libexec/src/runtime/proc.go:198 +0x212 fp=0xc42004bfe0 sp=0xc42004bf88 pc=0x1027c62
</span></span><span style="display:flex;"><span>runtime.goexit()
</span></span><span style="display:flex;"><span>        /usr/local/Cellar/go/1.10.3/libexec/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc42004bfe8 sp=0xc42004bfe0 pc=0x104e501
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>goroutine 5 [runnable]:
</span></span><span style="display:flex;"><span>time.Sleep(0x3e8)
</span></span><span style="display:flex;"><span>        /usr/local/Cellar/go/1.10.3/libexec/src/runtime/time.go:102 +0x166
</span></span><span style="display:flex;"><span>main.main.func1(0xc42007e180)
</span></span><span style="display:flex;"><span>        /Users/yusp/test/panic3/main.go:18 +0x61
</span></span><span style="display:flex;"><span>created by main.main
</span></span><span style="display:flex;"><span>        /Users/yusp/test/panic3/main.go:13 +0x59
</span></span></code></pre></div><p>It seems straightforward; Golang&rsquo;s map is not thread-safe, and concurrent read and write cause a panic. However, look at the error information on line <code>/Users/yusp/test/panic3/main.go:18 +0x61</code>, which points to line 18 of main.go where <code>Sleep</code> is called, not the actual point of concurrency issue. In a vast stack trace, it becomes even harder to locate the problem.</p>
<p>A workaround that comes to mind is if you only see the read stack and want to see the write stack, set a variable at the read position, reset it after reading, and check the value of this variable at the write position. If reading is currently happening, panic will be triggered.</p>
]]></content:encoded>
    </item>
    <item>
      <title>How to Use Monospaced Fonts in VS Code</title>
      <link>https://blog.minifish.org/posts/how-to-use-monospaced-fonts-in-vs-code/</link>
      <pubDate>Tue, 26 Dec 2017 22:21:06 +0800</pubDate>
      <guid>https://blog.minifish.org/posts/how-to-use-monospaced-fonts-in-vs-code/</guid>
      <description>The English font set in Microsoft&amp;#39;s VS Code is monospaced, while the Chinese font is not.</description>
      <content:encoded><![CDATA[<h2 id="background">Background</h2>
<p>The English font set in Microsoft&rsquo;s VS Code is monospaced, while the Chinese font is not.</p>
<h2 id="method">Method</h2>
<ol>
<li>Download and install the fonts from <a href="https://github.com/be5invis/Sarasa-Gothic">here</a>. This font combines Source Han Sans and is said to align punctuation strictly.</li>
<li>Use the method described <a href="https://github.com/be5invis/Sarasa-Gothic/issues/8">here</a> to set up VS Code.</li>
</ol>
<p>PS: It is indeed aligned, although the English text appears a bit narrow.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
