Website review
This review may include AI-generated content and is not individually verified. Domain, certificate and other facts come from the observed data on this page.
What is Win Tech Blog?
Win Tech Blog is a personal technical notebook by a Myanmar software engineer, published as a lightweight Jekyll-based blog. Its posts are short, experience-driven write-ups: Linux process and namespace debugging, SQL join fanout problems, WSL2 disk reclamation, JavaScript's event loop, and npm package structure. Content is mostly in English, with some posts in Burmese, so it reads as a working engineer's log rather than a polished publication.
Who it suits
- Software engineers who want quick, concrete notes on systems, Linux and databases
- Developers learning cloud networking or JavaScript internals from a peer's perspective
- Burmese-speaking engineers who prefer technical explanations in their own language
What to expect
- "Today I Learned" style posts tied to a specific problem and its fix
- Practical topics: process creation, memory management, namespaces, event loops, localization
- Occasional career and life writing, such as an account of studying in Canada
Trade-offs
Posts are dated and irregular, spanning 2018 to 2026, and the site has no clear course structure or beginner path. Depth varies with whatever the author was debugging, so treat it as a reference you search rather than a curriculum you follow. If you want structured Linux or networking material instead, The Linux Kernel Archives and MDN Web Docs cover fundamentals more systematically.
A useful next step: skim the tag list for Linux, SQL or JavaScript, pick one post matching a problem you currently have, and see whether the debugging narrative maps onto your own environment.
How do I fix the 'fatal library error, lookup self' when running unshare --pid?
The error usually means unshare can't resolve its own PID inside the new PID namespace — typically because /proc isn't mounted (or isn't visible) in that namespace, so the process can't look itself up. This is a known behavior when you create a PID namespace without giving it a working proc filesystem.
The fix
Mount /proc inside the new namespace. A common pattern:
unshare --pid --fork --mount-proc /bin/bash
--mount-proc makes unshare mount a fresh /proc for the new PID namespace automatically. The --fork is important: without it, the process that calls unshare stays as PID 1 in the old namespace and things get confusing. With --fork, a child becomes PID 1 of the new namespace and /proc lines up correctly.
If you're doing it manually:
unshare --pid --fork /bin/bash
mount -t proc proc /proc
Why it happens
- A new PID namespace starts with its own PID numbering; PID 1 is the first process.
- The
unsharebinary itself may try to read/proc/selfto figure out its PID. - If
/procstill points at the host's procfs (or isn't mounted), that lookup fails and you getfatal library error, lookup self. - Tools like
unsharefrom util-linux added--mount-procprecisely to avoid this.
Practical notes
- Use
--mount-procwith--pid --forkas the default combination. - Running as root (or with sufficient privileges) is usually required to create PID namespaces and mount procfs.
- If you're inside a container, the container runtime may already restrict namespace creation; check your seccomp/privilege settings.
- For quick experiments,
unshare --pid --fork --mount-proc bashthenps auxshould show only the processes in the new namespace.
Win Tech Blog covers related Linux namespace and process topics in its "Learning Notes" series — see Win Tech Blog for more on process creation and memory management.
Next step: Re-run your command with --fork --mount-proc added, then verify with echo $$ and ps -ef to confirm you're seeing the isolated PID space.
What causes SQL fanouts and how do I debug them?
SQL fanouts happen when one query row multiplies into many rows because it joins to a table where the matching condition isn't unique. The classic case is joining a parent to a child table on a non-unique key: one order row meets three order-item rows, and suddenly your revenue total triples. Aggregates like SUM, COUNT and AVG then compute over duplicated rows, so the numbers are wrong rather than the query failing.
Common causes:
- One-to-many joins treated as one-to-one. Joining
orderstoorder_itemsonorder_idwhen you only wanted order-level totals. - Multiple independent one-to-many joins in the same query. Joining both
order_itemsandpaymentstoordersproduces a Cartesian-style blow-up: rows multiply by both counts. - Missing or wrong join keys. A join condition that matches more rows than intended, often from a partial key or a
LIKE. - Duplicate rows in the "dimension" table. A lookup table with repeated natural keys silently fans out every fact row.
How to debug it
- Count rows at each stage. Run the query without aggregation and compare the row count to the base table. If
ordershas 1,000 rows and the joined result has 12,000, you have a fanout. - Check key uniqueness. For each joined table, run a quick
GROUP BY key HAVING COUNT(*) > 1to see whether the join key is actually unique. - Compare aggregate values with and without the join. If
SUM(amount)changes when you add a join, the join is duplicating rows. - Aggregate before joining. Compute per-entity totals in a subquery or CTE, then join those one-row-per-entity results. This is the most reliable fix.
- Use
COUNT(DISTINCT ...)as a diagnostic, not a permanent patch — it hides the fanout rather than removing it and can mask other issues.
The Win Tech Blog has a note titled "Debugging SQL Fanouts" in its Learning Notes series, filed under Database and SQL, which suggests the author hit this in practice rather than only in theory Win Tech Blog. That framing matches the usual reality: fanouts are rarely a syntax error, they're a silent correctness bug that shows up as a suspiciously large number in a dashboard.
A practical decision rule
Ask whether each joined table has at most one row per key in your result. If not, decide deliberately: either pre-aggregate that table to one row per key, or accept the multiplication and make it explicit in the query's intent. If you need totals from two independent child tables, don't join both to the same parent in one pass — aggregate each separately and combine them.
For a concrete scenario: an analyst joins customers to orders to line_items to report average order value. The average drops because each order is now counted once per line item. The fix is to compute order totals in a subquery first, then average those. The same pattern applies to any parent-child reporting query.
How can I reclaim disk space from WSL2's hidden disk file on Windows?
Freeing space in WSL2 means shrinking the virtual disk file (ext4.vhdx) that WSL2 keeps on your Windows drive. Deleting files inside WSL2 alone usually does not reduce Windows disk usage, because the virtual disk does not automatically give the space back. The page evidence includes a post titled "TIL - Reclaiming 160 GB from WSL2's Hidden Disk File," which notes exactly this: deleting files inside WSL2 does not shrink Windows disk usage, and one PowerShell command fixes it. The post is framed as the author's own "Today I Learned" note, so treat the workflow below as general guidance plus that observation, not a product specification.
The typical approach
- Confirm the space is actually held by the WSL2 virtual disk. In Windows, the file normally lives somewhere like
C:\Users\<you>\AppData\Local\Packages\<distro-package>\LocalState\ext4.vhdx. - Shut down WSL cleanly from PowerShell or Command Prompt with
wsl --shutdown. The disk file cannot be compacted while the distro is running. - Compact the virtual disk. The common built-in route uses
diskpart:diskpartselect vdisk file="C:\path\to\ext4.vhdx"attach vdisk readonlycompact vdiskdetach vdiskexit
- Restart your distro and check Windows free space again.
Where people get stuck
| Situation | What helps |
|---|---|
| Deleted files inside WSL2, no Windows space returned | Compact the ext4.vhdx file; deletion alone is not enough |
| Compaction refuses to run | Run wsl --shutdown first and make sure no terminal or editor is holding the distro open |
| WSL2 stores the disk on a different drive | Point diskpart at the actual .vhdx path, not the default one |
| You want a repeatable routine | Keep the shutdown-and-compact steps as a short script you run occasionally |
A concrete scenario
Say you have been building Docker images, node_modules folders and large datasets inside Ubuntu on WSL2 for a year. You delete several dozen gigabytes and Windows still shows a nearly full C: drive. That is the normal behaviour: the virtual disk grew to its high-water mark and stayed there. Shutting down WSL and compacting the disk is the step that returns the space.
Decision criteria
- If you only need space back occasionally, the manual
diskpartsequence is enough. - If you delete large files often, consider keeping data on the Windows filesystem or an external drive instead of inside the WSL2 disk, so Windows can reclaim it directly.
- Before compacting, make sure you have a backup of anything irreplaceable inside the distro; disk operations on a virtual disk are not the moment to discover you have no copy.
For a fuller walkthrough of this exact problem, the author's note at Win Tech Blog is a reasonable starting point, since it describes the same symptom and the single-command fix.
How does JavaScript's event loop task queue handle asynchronous operations?
JavaScript's event loop lets a single-threaded language appear to handle many things at once: instead of blocking on slow work, it queues callbacks and runs them when the call stack is free. The task queue is where those callbacks wait their turn.
The basic cycle
- Synchronous code runs to completion on the call stack.
- When the stack empties, the event loop checks the task queue.
- It takes the first queued callback and runs it.
- After that callback finishes (and the stack is empty again), it looks for the next one.
So asynchronous operations don't run in parallel inside JavaScript itself. The environment around it — the browser or Node.js — handles timers, network responses and I/O, then places the associated callback in a queue for the loop to pick up.
Where it gets subtle
There isn't just one queue. Timers and I/O callbacks go to a macrotask queue, while promise callbacks go to a microtask queue that is drained before the next macrotask runs. That ordering is why a resolved promise's .then often fires before a setTimeout scheduled at the same moment, even with a delay of zero.
A useful mental model for a reader debugging confusing output:
- Stack first — finish the current function.
- Microtasks next — drain all promise callbacks.
- One macrotask — then repeat.
The Win Tech Blog covers this topic directly in its note on how the Task Queue works inside JavaScript's Event Loop, written for developers who want the practical picture rather than the full specification. The blog also collects related learning notes on Linux processes and namespaces, which makes it useful if you're moving between application-level and system-level concurrency concepts.
A concrete next step
Write a small script that logs "A", schedules a setTimeout(..., 0) that logs "B", and chains a resolved promise that logs "C", then logs "D" synchronously. Predict the order before running it. Getting that prediction right is the quickest way to confirm you actually understand the queueing model — and if it surprises you, that gap is exactly what to study next.
What is the basic networking knowledge software engineers need for cloud work?
The short answer: you do not need to become a network engineer, but you do need a working mental model of how traffic moves between your code and the outside world. The Win Tech Blog frames its networking note around exactly this gap — it targets software engineers, and notes that the material is easy for networking specialists but often hard for engineers, since in many organisations the work is already set up and handled by DevOps or cloud engineers. That framing is useful: your goal is to read and reason about the setup, not to replace the people who maintain it.
The core topics worth learning
- IP addresses, subnets and CIDR notation — enough to read
10.0.1.0/24and know roughly how many hosts that covers and whether two addresses are in the same range. - Ports and protocols — that HTTP, HTTPS, SSH and database traffic use different ports, and that a port being closed is a different failure from a host being unreachable.
- DNS — how a hostname becomes an address, and why a name that resolves from your laptop may not resolve from inside a private network.
- Routing basics — default gateways, route tables, and why a service on one subnet can reach another only if routing and rules allow it.
- NAT and public versus private addressing — why your instance has a private address and reaches the internet through something else.
- Firewalls and security groups — the difference between a rule that blocks traffic and an application that is simply not listening.
- Load balancers and proxies — what they add, and why client IPs and TLS termination behave differently behind them.
- TCP versus UDP at a practical level — connection-oriented versus fire-and-forget, and when retries or ordering matter.
A concrete debugging scenario
A service works on your machine but times out when deployed. Walk the layers in order: does DNS resolve the target name from inside the network, is the destination address in a reachable subnet, does a route exist, does the security rule permit the port, is the process actually listening on that interface rather than only on localhost, and does the response come back through the same path? Most cloud connectivity bugs land on one of those steps, and knowing the order saves hours of guessing.
How to decide what to learn next
If you mostly deploy behind managed infrastructure, prioritise DNS, security rules and reading logs over deep protocol internals. If you design VPCs, subnets and peering yourself, spend time on CIDR planning and route tables first, because mistakes there are expensive to undo. If you debug latency or intermittent failures, TCP behaviour and load balancer settings deserve attention.
For a broader reference on how these pieces fit together in cloud environments, Amazon Web Services publishes architecture and networking documentation, and Google Cloud covers similar ground from a different vendor's perspective. Reading one vendor's concepts carefully transfers well to the others, since the underlying ideas — subnets, routes, rules, load balancing — are largely shared.
User reviews (0)