惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
Engineering at Meta
Engineering at Meta
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
B
Blog RSS Feed
GbyAI
GbyAI
P
Proofpoint News Feed
aimingoo的专栏
aimingoo的专栏
MyScale Blog
MyScale Blog
D
Docker
阮一峰的网络日志
阮一峰的网络日志
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recorded Future
Recorded Future
美团技术团队
The Register - Security
The Register - Security
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
The Blog of Author Tim Ferriss
博客园 - 司徒正美
量子位
B
Blog
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
L
LangChain Blog
Latest news
Latest news
S
SegmentFault 最新的问题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
W
WeLiveSecurity
T
Tenable Blog
T
Tor Project blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Froot Loops and a graphics card
Daniel May · 2026-05-13 · via DEV Community

Published on US Mother's Day, 2026.

The email arrived on the 4th of December 2006, forwarded by my dad from Bill, an engineer at the company my dad was contracting at. I was 14. Bill had attached a zip file containing an HTML page with PHP scriptlets embedded inline, written by someone at the company four years earlier, plus a sample text dump from a Siemens 9005 digital PBX. The file was named parsebev3.html, after Bev, the user who actually ran the parser every day. There were already three versions of a parser-for-Bev. The job was to make a fourth, in a Windows desktop application.

Main parser window: Input file textbox,

If your son can take a look at this and see how easy it might be to do, I would appreciate it. I think rather than rewrite it as an ASP.Net app it might be better to just create a Windows based .net application. Either VB or C##. I'm sure we could figure out some way to compensate him for his work, talk to Candi.

Candi, Bill's wife, was also in the email; she would handle compensation. With Bev, the three of them were a small-shop cast of characters this project belonged to more than it ever belonged to me.

The Siemens 9005 was a digital PBX, the kind that handled switching for offices that still ran their own phone systems. Each extension on the switch had a stack of feature programming attached: class of service, hunt-group memberships, forward-on-busy targets, forward-on-no-answer targets, ACD assignments. The switch dumped this all as a structured-but-fiddly text format, and downstream of that someone needed to pull the dump into Excel to actually look at the configuration. That was the job. Read the text dump, parse the per-extension records, output TSV.

I downloaded the zip, looked at the PHP for a bit, and started writing. I picked VB6.

Bill's email had recommended VB.NET or C#. I'd already been writing VB6 for a couple of years by then, mostly on web-automation tooling for browser games. My copy was cracked, because I was a kid and had no money. I'd tried VB.NET a year or so earlier with Sams Teach Yourself VB.NET 2003 in 21 Days. The language itself was fine. The tooling shift from VB98 to the .NET ecosystem, and the DLL hell that came with it, was where I got stuck. So I went back to VB6. It wasn't a naive choice; it was what got the parser shipped.

There was no Siemens 9005 dump-format spec on the internet that I could find. The format had to come from reading the PHP, which itself was probably someone's empirical reading of a few sample dumps. So I did, opened the sample dump in Notepad, and wrote down what I saw at the top of my own module. The first chunk looked like this:

  '   Field                       Posn        Length
  '
  '   Extension                   1           7
  '   Type                        9           4
  '   COS                         14          3
  '   Target 1                    18          8
  '   ...
  '   Forward DND External        64          1

Enter fullscreen mode Exit fullscreen mode

The full spec, all of it written into the comments at the top of the module before any executable code, was about 100 lines of "find this anchor, then offset by N for a field of length L." Records were bracketed by RINGDOWN (start) and FORWARD (end). Inside each record, the first DS anchored the basic fields. The second DS anchored ACD and NAME. Optional sections were anchored by G R O U P and T E R M I N A L, with literal single-space gaps between every letter. A 1990s PBX serializing its terminal-info section header as letter-spaced ASCII is the kind of detail you don't get to pick up unless you've stared at the actual output.

The code that followed the spec was a faithful translation of the comments:

  intRecStart = InStr(intRecFinish, strBuffer, "RINGDOWN") + 2
  intRecFinish = InStr(intRecStart, strBuffer, "FORWARD")
  strRecord = Mid$(strBuffer, intRecStart, intRecFinish - intRecStart)

  intFirstDS = InStr(1, strRecord, "DS") + 2
  strEXT(intRecordCount)     = Mid$(strRecord, intFirstDS + 1, 7)
  strTYPE(intRecordCount)    = Mid$(strRecord, intFirstDS + 9, 4)
  strCOS(intRecordCount)     = Mid$(strRecord, intFirstDS + 14, 3)
  strTARGET1(intRecordCount) = Mid$(strRecord, intFirstDS + 18, 8)

Enter fullscreen mode Exit fullscreen mode

InStr to find an anchor, Mid$ to take a substring of fixed length at a hardcoded offset. That is the entire parsing technique. The PHP had done the same thing with its substring functions; I did it four years later with Mid$. The format determines the technique more than the language does.

The terminal-info section had the most fiddly parsing. Up to twelve terminal entries per record, four banks of three terminals each, with each bank anchored by its own DS. Empty slots were marked with * characters in specific positions, so the code had a chain of If InStr(strCSTYPE5, "*") > 0 checks, each clearing the relevant slot and setting an intStopFlag to short-circuit further bank reads. The whole thing reads like every fixed-width parser ever written: a stack of conditional fall-throughs, half of them defending against quirks in the upstream output that a real spec would have ruled out.


The parser was the job. The rest of the application is where the kid version of me showed what he thought real Windows applications were supposed to look like.

The custom button user-control on the Go button supported nine styles: Flat, Java, OfficeXP, WindowsXP, WindowsTheme, Plastik, Galaxy, Keramik, MacOSX. Two of those (Plastik and Keramik) are KDE themes. There is no reason a single-user Windows VB6 application needed nine button styles. I put them all in because the user-control I'd downloaded supported them, and I let Bev pick from a Settings dialog because I'd built a Settings dialog that did INI-backed persistence and I might as well give it something to remember.

Six button styles rendered by the custom user-control

A debug-mode menu, when toggled, streamed the parser's narration into a textbox on a separate form. Debugtxt "Parsing record " & intRecordCount, called from inside the parser. I built a logging system because I'd decided real Windows applications had logging.

The folder-output picker used a Win32 SHBrowseForFolder integration so it would be a native Explorer-style dialog. I didn't use it for the file picker, which was a CommonDialog. Why two? Because the docs I'd read for browsing a folder said SHBrowseForFolder, and the docs for opening a file said CommonDialog, and I did not yet know to question why.

Settings dialog: record-type toggles, output options, and the Button Styles dropdown

On the About screen, clicking the IHS logo brings up a Froot Loops image, which I had forgotten was there.

About dialog. Clicking the IHS logo reveals a hidden Froot Loops image.

What shipped did the job. Open a file, hit Go, get a TSV that opened in Excel. None of it was in source control; I'm lucky still to have the source twenty years later, copied from drive to drive. Each release went past my dad as code reviewer first. The application went into Bev's daily workflow and replaced the PHP/HTML thing.

I got paid. The compensation, sorted out by Candi, was a case of Froot Loops (I'd been to Florida earlier that year and gotten weirdly into them at breakfast; this was a known fact in the family, deployed) and an Nvidia GeForce 7950 GT. Generous, by 14-year-old PC-gamer standards. A graphics card was the right shape of payment. The Froot Loops were the joke. Both arrived.

XFX-branded Nvidia GeForce 7950 GT, the graphics card in question.

What stays with me is Candi at her kitchen table, wondering what would keep a passionate young boy interested in technology.


Twenty years of writing software since this parser, what I notice is how much of what I've been paid to do was a more sophisticated version of the same job: take this stream of bytes from over here, derive what's interesting in it, deliver it in a shape over there. The Siemens dump in 2006, an FX trade ticker in 2011, a fleet of Whole Foods in-store handhelds in 2019, an Amazon promotion-planner in 2022, a VALORANT build event in 2024. Structurally the same problem, dressed up in the conventions of their domain. The companies paying for the work cared about the dressing-up, which is fair, because that's where the business value was. The shape of the work itself was almost always point-to-point ETL with a UI on top.

That category of work makes up a huge fraction of paid software, and a lot of what I've shipped since 2006 is still shaped that way. An LLM with a sample dump and a sample output can produce most of the syntactic legwork of fourteen-year-old me's parser in an afternoon today. The InStr/Mid$ scaffolding, the output formatters, the glue between the settings dialog and the parser, all of that collapses.

The hours that don't collapse are the judgment ones. The Siemens dump didn't mark "no more terminals here" with a clean sentinel; it put a * character in some positions where data would otherwise be, and you had to know which field within each bank was the reliable diagnostic. You read sample dumps until you saw the pattern, then baked your intuition into a check. An LLM can produce the check once you've told it where to look; it can't tell you where to look without you having looked.

The personality of a thing built by a specific person who cared about it also doesn't come out of an LLM. Nine button styles because the user-control supported KDE and Mac OS X and Java themes; a status bar reading "Status: Idle" because something at the bottom of the window had to; a whole debug-mode menu because real Windows applications had logging. None of those are LLM-generated defaults. They're the marks of someone who cared what their software looked like, even when only Bev was going to see it.

I would not wish a Siemens 9005 dump format on a 14-year-old. But the era did produce engineers, and the kind of engineer it produced was comfortable with messy real input, with a one-button UI for an audience of one, with shipping the thing and finding out what to defend against once it was in production. My best LLM-assisted work has rested on instincts I learned writing software like this: static types catching my mistakes for me, behavioral tests for the parts of a system I don't fully hold in my head, the simple knowing-where-to-look that comes from staring at enough sample dumps. What an engineer whose first thousand hours doesn't include any of that ends up with, I don't know.

The parser is still on my NAS. The Froot Loops are long eaten. As for the graphics card, it lived in three different machines before dying, sometime around 2010, in a case I built in the garage. I miss the era a little, not for the tools but for the shape of the work.


Bill is retired now, works as a photographer in Colorado, and my dad has visited him there several times. I'm grateful for the chance he took on me. Candi, his wife and a mother, passed from breast cancer in 2014. If this post left you thinking of someone who took a chance on you, consider Susan G. Komen or Cancer Research UK, in her memory.

Originally published at danielmay.co.uk.