
      
      
      
    
      
      
      
    
      
      
      
    
      
      
      
    
      
      
      
    
      
      
      
    
      
      
      
    [{"authors":null,"categories":null,"content":"I moved my blog (the one you’re reading now) onto Amazon Web Services . I was only paying about $10–$15 per month to host on GoDaddy, but it still felt too expensive. After all, my little blog doesn’t get much traffic these days 😭. It’s also important to me that I treat every development and deployment opportunity as a learning experience. A turnkey hosting service robs you of the chance to learn about the different components and layers in the website deployment process. This post recounts my setup process so that you, the reader, can follow this and deploy your own site on the cheap.\nNote: Do not try this unless you want to become your own devops team + system administrator\nThere is also a long-term benefit I will reap in addition to putting knowledge in my noggin. A managed host is a fine on-ramp, but you’re renting someone else’s opinions about caching, headers, redirects, and TLS. Running it myself on AWS means I own every one of those knobs — and the bill scales with actual traffic, which for a blog rounds to nothing. But there’s also a longer game: the same account that serves this site can grow into whatever I build next, without a migration. I’m planning to deploy some SPAs for fun and/or profit in the mid-future. Consider this blog deployment the prototype for future web apps.\nThis post gives the whole setup, start to finish, using only the AWS CLI . I originally created everything by console clicking. If you follow this to the end you’ll have a private S3 bucket served over HTTPS through CloudFront , a real certificate from AWS Certificate Manager , DNS in Route 53 , and a deploy that’s a single aws s3 sync.\nThe architecture Route 53 (apex + www, A/AAAA alias records) │ ▼ CloudFront distribution ── ACM cert (us-east-1, *.example.com) • redirect-to-HTTPS CloudFront Function (viewer-request): • HTTP/2 + HTTP/3 /dir/ → /dir/index.html • caches at the edge CloudFront Function (viewer-response): security headers │ Origin Access Control (SigV4) │ (signed, HTTPS only) ▼ Private S3 bucket ── bucket policy allows ONLY (Block Public Access this distribution\u0026#39;s CloudFront fully ON) service principal Notes:\nThe bucket is private. Nobody reaches S3 directly — CloudFront authenticates to it with Origin Access Control (OAC) , and a bucket policy trusts only this one distribution. Visitors only ever touch the CDN edge. An alias record is a special Route 53 entity that maps a DNS name to an AWS resource (CloudFront distribution) instead of an IP address. Prerequisites An AWS account and the CLI installed and authenticated (aws sts get-caller-identity should work). A registered domain. I’ll use example.com throughout — substitute yours. A built static site. I use Hugo ; any generator that outputs a folder of files works. Set a few shell variables so the commands below are copy-pasteable:\n1 2 3 4 DOMAIN=example.com BUCKET=example-site # NOTE: no dots — this matters, see the gotchas REGION=us-east-1 ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) A quick word on Hugo Hugo is my site generator of choice. I won’t belabor it — but you can go info diving if you’re interested . The only thing that matters for hosting is that something builds your entire site into a public/ directory of plain files:\n1 hugo --gc --minify # output lands in ./public That folder — containing root index.html, per-page index.html files, images, CSS — is the artifact we ship to S3. Hold that thought; the very last step is a one-liner that copies it up.\nStep 1 — Create the private S3 bucket 1 2 3 4 5 6 7 8 9 10 11 12 # In us-east-1 you do NOT pass a LocationConstraint; every other region requires it. aws s3api create-bucket --bucket \u0026#34;$BUCKET\u0026#34; --region \u0026#34;$REGION\u0026#34; # Block public access — all four switches, at the bucket level. aws s3api put-public-access-block --bucket \u0026#34;$BUCKET\u0026#34; \\ --public-access-block-configuration \\ BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true # Default server-side encryption. aws s3api put-bucket-encryption --bucket \u0026#34;$BUCKET\u0026#34; \\ --server-side-encryption-configuration \\ \u0026#39;{\u0026#34;Rules\u0026#34;:[{\u0026#34;ApplyServerSideEncryptionByDefault\u0026#34;:{\u0026#34;SSEAlgorithm\u0026#34;:\u0026#34;AES256\u0026#34;}}]}\u0026#39; New buckets already default to BucketOwnerEnforced (ACLs disabled), which is what you want — access is governed entirely by the bucket policy we’ll add later, not by per-object ACLs.\nWhile you’re here, you can lock the whole account down so a future bucket can’t accidentally go public:\n1 2 3 aws s3control put-public-access-block --account-id \u0026#34;$ACCOUNT_ID\u0026#34; \\ --public-access-block-configuration \\ BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true Step 2 — Request a TLS certificate from ACM (in us-east-1) CloudFront can only use certificates from us-east-1, no matter where your users are. Request one for the apex (example.com, no www in front) plus a wildcard (*.example.com), validated by DNS :\n1 2 3 4 5 6 7 8 9 10 CERT_ARN=$(aws acm request-certificate \\ --domain-name \u0026#34;$DOMAIN\u0026#34; \\ …","date":1780833600,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1790035697,"objectID":"d7f3fb4c0d13e9785bbef17e7b651891","permalink":"https://mikejfromva.com/post/hosting-a-hugo-site-on-aws/","publishdate":"2026-06-07T08:00:00-04:00","relpermalink":"/post/hosting-a-hugo-site-on-aws/","section":"post","summary":"A complete, copy-pasteable walkthrough of hosting a static site on AWS with nothing but the CLI: a private S3 bucket fronted by CloudFront with Origin Access Control, an ACM certificate, Route 53 DNS, and a one-line deploy with aws s3 sync --delete. Plus the two gotchas that cost me an afternoon — dotted bucket names and the CloudFront free plan — and what it all costs (about a dime a month).","tags":["aws","s3","cloudfront","route53","acm","hugo","devops","self-hosting"],"title":"Hosting a Static Site on AWS, End to End (S3 + CloudFront + OAC + Route 53 + ACM)","type":"post"},{"authors":null,"categories":null,"content":"In November 2002, two papers were presented at SC2002 — the ACM/IEEE Supercomputing conference, held that year in Baltimore. Software engineers at Sun Microsystems authored both papers, and I supported their efforts by providing data.\nSMP System Interconnect Instrumentation for Performance Analysis (IEEE Xplore ), by Lisa Noordergraaf and Robert Zak Ultra-High Performance Communication with MPI and the Sun Fire Link Interconnect (IEEE Xplore ), by Steven J. Sistare and Christopher J. Jackson I worked closely with the paper authors to dig deep into benchmarks and performance metrics, reconfiguring hardware between benchmark runs and isolating workloads with interesting results within the benchmarks themselves. That’s the job I want to write about in this post - what performance engineering at a hardware company actually looked like in 2002, and why it was unlike most software work I have done before or since.\nPerformance Engineering Is a Different Kind of Software Job Most software development is about building features. You take a requirement, you turn it into code, you ship it, and the measure of success is whether it does the thing it was supposed to do.\nPerformance engineering barely resembles that. I spent comparatively little time writing application code. Instead, I spent my time:\nStudying hardware. Reading processor manuals, interconnect specifications, and cache-coherence protocols closely enough to reason about them. Gathering performance metrics by running demanding math and science simulations — the kind of workloads that actually stress a machine. Analyzing the resulting data and, just as importantly, explaining my conclusions to people who would act on them. Building proof-of-concept implementations — not products, but small, sharp demonstrations that a particular change would move the needle on particular hardware. The deliverable was usually not software. It was understanding. A performance engineer’s product is a defensible claim: “On this processor, with this workload, the bottleneck is here, and here is the evidence.” The two SC2002 papers are, in a sense, the polished public form of exactly that kind of claim.\nWhat the Papers Were Actually About Both papers orbit the same hard problem: in a large symmetric multiprocessing (SMP) machine, the system interconnect — the fabric tying processors, memory, and I/O together — is very often the thing that limits performance. Not the processors. The wiring between them.\nThe first paper describes hardware instrumentation embedded in the Sun Fire Link interconnect: programmable filters, histogramming counters, and a small transaction-sequence buffer that let performance analysts see what kinds of transactions were crossing the Sun Fireplane interconnect, where they were going, and which caches were involved. One noteworthy result is a cache-conflict detection tool: by capturing write-back transactions and computing which cache block each evicted address mapped to, you could literally produce a scatter plot of cache pain and point at the hot spot.\nThe second paper is about turning a rack of big SMP servers into a single capability cluster using the Sun Fire Link interconnect and a custom MPI library built on remote shared memory. The headline numbers — MPI ping-pong latency as low as 3.7 microseconds and inter-node bandwidths near 3 gigabytes per second — were striking enough that off-node performance often matched on-node performance. A job sometimes ran faster spread across two machines than packed into one. That work was funded in part through the U.S. Department of Energy’s ASCI PathForward program via Lawrence Livermore National Laboratory — supercomputing money, chasing supercomputing problems.\nThe Hardware Landscape of 2002: NUMA, OpenMP, and MPI To appreciate why this work mattered, you have to remember what parallel computing looked like at the time.\nBy 2002 the free lunch of ever-faster single processors was visibly ending, and the industry’s answer was more processors — which immediately raises the question of how they share memory. A small SMP machine can pretend all memory is equidistant. A large one cannot. Physics intervenes: memory attached to the board your thread is running on is closer, and faster to reach, than memory three boards away. That is NUMA — Non-Uniform Memory Access — and it was becoming unavoidable. The cache-conflict tool in the first paper even reports which physical bank and system board each address lived on; locality was not an abstraction, it was a wiring diagram.\nSoftware had two main answers, and the SC2002 papers touch both:\nOpenMP — a shared-memory model where you annotate code with compiler directives and the runtime spreads loops across threads. The first paper profiles applications from the SPEC OMP (SPEComp) suite. MPI — a message-passing model where independent processes explicitly send data to one another, the standard approach for spanning many machines. The second paper is an MPI implementation end to …","date":1779188400,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1780749248,"objectID":"b770373cf2185db6c791fc4f843e87cd","permalink":"https://mikejfromva.com/post/retrospective-2002-performance-engineering-at-sun/","publishdate":"2026-05-19T07:00:00-04:00","relpermalink":"/post/retrospective-2002-performance-engineering-at-sun/","section":"post","summary":"A retrospective on my work as a performance engineer at Sun Microsystems — two Supercomputing 2002 papers I gathered data for, the NUMA-and-MPI hardware landscape of the era, the UltraSPARC processors measured against the 6502 of my childhood and the CPUs of today, why the CISC-versus-RISC mental model is long past its expiration date, Tanenbaum's register-less stack machine, and how a memcpy change shipped in Solaris.","tags":["retrospective","sun microsystems","performance","computer architecture","cpu","solaris","personal"],"title":"Retrospective 2002: Performance Engineering at Sun Microsystems","type":"post"},{"authors":null,"categories":null,"content":"I’ve interviewed with Google, Apple, Amazon, MongoDB, Capital One, and countless others. Every one of them put me through a coding interview, with wildly varying degrees of difficulty. I could say a lot more about that — but it’s the kind of topic that almost demands feedback and pushback, so you can leave your opinion or ask for mine in the comments below.\nThe languages varied as much as the difficulty did. I once had an interview where every line had to be delivered in Python — and another where I was offered the choice of literally any language, except Python.\nA Little History I’m genuinely happy to be working in an era where remote work for software engineers is normalized. Mind you, this isn’t new to me. I worked remotely, full-time, as far back as 2004–2005 — for Sun Microsystems . Sun was a company ahead of its time in some ways, and out of time in others (LOL). It was eventually acquired by Oracle , and a lot of what made it special got absorbed and rearranged.\nThere’s no shortage of interview prep material online these days. In my time, I leaned on Cracking the Coding Interview by Gayle Laakmann McDowell — the book this whole repository is named after. Its companion site, HackerRank , is a lot of fun. I’m not a competitive-coding person, but I enjoy taking a swing at the challenges there now and then.\nBack in 2019 I was job hunting, and I wanted to be prepared. The exercises below are some of the practice problems I worked through, collected in my Cracking-the-Coding-Interview-in-Java repository. They contain a combination of puzzles, like what you might see in a job interview, and deep dives into complex algorithms using source material - just to get my brain working on following detailed instructions.\nOne heads-up if you click into the code: the variable names are short and the style is deliberately terse. I wrote these in a whiteboard-coding frame of mind, where spelling out long, descriptive names costs you time you don’t have. It’s not how I write production code — it’s how you write code with a marker in your hand and an interviewer watching the clock.\nThe Puzzles Add Without Arithmetic — Add two integers without using + or any arithmetic operator at all — only bitwise logic, propagating the carry one bit at a time across all 32 bits. A classic test of whether you really understand two’s complement .\nUnique Characters — Determine whether every character in a string is unique, with the twist that you’re not allowed any additional data structures. The repo solves it recursively in O(n²) to honor that constraint, then adds a bonus O(n) version for when a lookup table is allowed.\nCompound Words — Decide whether a word can be assembled entirely from a dictionary of smaller words — “houseboat” from “house” plus “boat”. There are two implementations: a straightforward slow recursion, and a faster one backed by a sorted set.\nWord Ladder — Given two equal-length words and a dictionary, transform one into the other one letter at a time, where every intermediate step is itself a real word: DAMP → LAMP → LIMP → LIME → LIKE. It’s a word ladder puzzle, and under the hood it’s a breadth-first search .\nRabin–Karp String Search — Find a pattern inside a larger string using a rolling hash, so most non-matching positions can be rejected with a single cheap comparison instead of a full character-by-character scan. (Rabin–Karp )\nRemove Duplicates from a Linked List — Walk an unsorted singly-linked list and splice out repeated values, using a hash set to remember what’s already been seen.\nReverse a Tree’s Siblings — Take a tree stored in child/sibling representation and reverse every sibling list, from the root all the way down. Easy to describe, and genuinely fiddly to get right with pointers.\nSelect Random — Pick m integers at random from an array of n, with no repeats — a partial Fisher–Yates that does just enough shuffling to fill the result.\nShuffle — Shuffle a deck in place with the full Fisher–Yates algorithm — every ordering equally likely, no bias.\nBomberman — On a 2D grid of walls, badguys, and empty space, find the single spot where dropping a bomb takes out the most badguys. The blast travels down its row and column until a wall stops it. The whole grid is solved in one O(N) sweep.\nMinimum Spanning Trees: Kruskal \u0026amp; Prim — Two classic graph algorithms aimed at the same target — finding the minimum spanning tree of a weighted graph. Kruskal’s sorts the edges and leans on a disjoint-set (“union-find”) structure to avoid cycles; Prim’s grows the tree outward from a starting node. The union-find itself is implemented here as weighted quick-union with path compression — an intereting data structure that’s a complex piece of engineering in its own right.\nClosing If any of these bring back your own interview war stories or classroom nostalgia — triumphant or traumatic — let us know in the comments below!\n","date":1778947200,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1780748856,"objectID":"fd0ab13ad93328ee3037ca4d05dcfde2","permalink":"https://mikejfromva.com/post/retrospective-2019-coding-interviews/","publishdate":"2026-05-16T12:00:00-04:00","relpermalink":"/post/retrospective-2019-coding-interviews/","section":"post","summary":"A retrospective on practicing for software engineering coding interviews in 2019 — a little history, some opinions on remote work and prep materials, and a tour of every puzzle in my Cracking-the-Coding-Interview-in-Java repository.","tags":["retrospective","java","algorithms","interviews","personal"],"title":"Retrospective 2019: Coding Interviews","type":"post"},{"authors":null,"categories":null,"content":"In 2013 I published a paper titled Beam Viewer Controls at Jefferson Lab through the International Conference on Accelerator and Large Experimental Physics Control Systems (ICALEPCS) , held that year in San Francisco. The paper details a complete rewrite of the control system software responsible for managing beam viewer devices on the 12 GeV CEBAF particle accelerator at Jefferson Lab in Newport News, Virginia.\nYou can read the paper on ResearchGate: Beam Viewer Controls at Jefferson Lab . There is something genuinely satisfying — and very cool — about searching for your own name on a research database and finding a published paper staring back at you. For an engineer who spent years in the trenches writing C++ and debugging hardware signals, seeing that work preserved and indexed alongside physics research from around the world is a quiet kind of thrill.\nWhat Is Jefferson Lab? Jefferson Lab (formerly the Thomas Jefferson National Accelerator Facility) is a U.S. Department of Energy facility dedicated to nuclear physics research. Its crown jewel is CEBAF — the Continuous Electron Beam Accelerator Facility — a large electron accelerator used to probe the internal structure of protons and neutrons. At the time of this work, the lab was in the middle of a major upgrade from 6 GeV to 12 GeV beam energy, roughly doubling the machine’s experimental reach.\nRunning an accelerator of this scale requires not just physics expertise but an enormous amount of software. Control systems touch everything: magnets, power supplies, diagnostics, safety interlocks, and the devices I worked on — the beam viewers.\nThe Problem Beam viewers are physical devices inserted into the beamline to give operators and physicists a picture of the electron beam’s shape and position. Think of them as tiny fluorescent screens that you slide into the path of the beam to see a glowing spot. Over 140 of these devices were installed on the 12 GeV machine, along with Faraday cups, insertable dumps, and other devices that share the same basic mechanics: a motor drives them in or out, limit switches confirm their position, and cameras route video back to the control room. Complicating matters, some of the devices were thin and fragile enough that the beam at full power would burn right through. Failure to check beam power before moving a device could result in weeks of shutdown to clean and repressurize the beamline.\nThe legacy software managing all of these devices dated back to the 1980s. It was a sprawling system built in State Notation Language running on 20 Input/Output Controllers spread across the accelerator tunnel — roughly 9,000 lines of SNL code, 2,000 lines of C, and hundreds of configuration files. When a device failed, diagnosing it meant hunting through a maze of EPICS records. Adding a new device meant editing configuration files in dozens of places. The system was difficult to maintain and nearly impossible to extend cleanly.\nThe New Design My replacement system, the Insertables System, took a data-driven approach. All device configuration — type, position, hardware channel assignments, beam vulnerability — was consolidated into a single structured XML file. A C++ program called the Insertables Manager read that file at startup, constructed a model of the entire system, and ran a background coordination loop that responded to hardware events through EPICS Channel Access.\nThe key insight was organizing devices into C++ sets reflecting their current state: inserted, retracted, traveling, lost, hardware-protected. When a beam viewer was requested for insertion, the Coordinator checked the inserted set for any inline devices that needed to clear first, sent retraction signals to all of them, and only then allowed the viewer to move. When a device went lost — no limit switch response within a timeout — the system automatically limited beam current until an engineer resolved the hardware issue, and the status string told them exactly which device had failed and why.\nThe EPICS database was reduced from hundreds of configuration files to a handful of macro-driven templates. Adding a new device now meant adding a few lines of XML and loading one additional template file at IOC boot time.\nDebugging by Ear Here is something that did not make it into the paper.\nDuring development and testing, I would sometimes sit near the beamline with a laptop and test the software in place. When a viewer received an insertion command, the actuator would fire — and if you were close enough, you could hear it: a soft, definitive plunk as the device settled into position. I would watch my screen for the limit switch signal to confirm the move had registered in software, while listening for that sound to confirm the hardware had actually responded. If the plunk came without the software registering it, I had a wiring or configuration problem. If the software showed the move but there was no plunk, something was wrong on the hardware side.\nIt is a small thing, …","date":1778286900,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1778356292,"objectID":"97447044f22769ae661f4dc10bdcc6bc","permalink":"https://mikejfromva.com/post/retrospective-2013-beam-viewer-controls/","publishdate":"2026-05-08T20:35:00-04:00","relpermalink":"/post/retrospective-2013-beam-viewer-controls/","section":"post","summary":"A retrospective on building control software for Jefferson Lab's 12 GeV CEBAF particle accelerator — the design of the Insertables System, debugging hardware by listening for actuator sounds at the beamline, and missing the ICALEPCS conference due to the federal government shutdown.","tags":["retrospective","jefferson lab","physics","science","c++","epics","personal"],"title":"Retrospective 2013: Software Built to Run a Particle Accelerator","type":"post"},{"authors":null,"categories":null,"content":"Back in the late ’80s I played a game called Cosmic Glob on my Atari 130XE . The Atari ran on a 6502 CPU — the same processor that powered the Atari 2600 game console. When people hear “Atari,” they usually picture that console, but Atari also built a line of full home computers, and in those days magazines dedicated to Atari computing used to come with pages of BASIC and assembly code that you could type in by hand. Manually. Every line. If you made a typo, you debugged it yourself.\nI typed in one such game — Cosmic Glob — and my brother and I wore it out. You can see a demo of it on YouTube . The gameplay was a riff on Asteroids : avoid the enemy, shoot everything, don’t die. But Cosmic Glob had a twist that I’ve never seen replicated anywhere. When you shot another player, instead of destroying them it pushed them — hard — in the direction you were firing. Your bullet was a physics impulse, not a kill shot. You could use that to run your opponent into an obstacle, or just knock them across the screen for laughs. My brother and I spent far more time harassing each other than actually fighting the enemy Glob. That little mechanic turned a solo arcade game into a chaotic social experience, and I’ve never forgotten it.\nEnter Claude Code Last week I subscribed to Claude Code Pro and decided to put it through its paces by having it recreate that game — Cosmic Blob, my modernized tribute to the 1986 original.\nI started with the simplest possible scaffolding: an asteroids-style ship with arrow key controls for rotate, thrust, and flip. I deliberately left out momentum — when you release the key, the ship stops immediately. That makes the game easier to follow and keeps the feel closer to the quick, snappy controls of the original rather than the floaty physics of classic Asteroids. Claude gave me exactly what I asked for, including a procedurally generated starfield.\nFrom there I built the game up one feature at a time: obstacles, synthesized sound effects, the Blob itself, a pause feature, and finally a second player. As the game grew more complex, bugs crept in. For example, when the game was paused it would continue playing sounds in an infinite loop. We tracked down and squashed each one.\nAlong the way I exhausted my five-hour token limit twice. Code generation is clearly more token-intensive than tasks like refactoring or targeted bug fixes, and this was not a small project. Something to keep in mind for future sessions.\nIn the end, Claude Code produced roughly 1,100 lines of JavaScript in a self-contained single-page app, organized cleanly with clear constants, well-named functions, and good separation of concerns. If I want to tune something — say, the Blob’s size or hit points — I can find it immediately.\nHow the Code Works The whole game lives in a single HTML file with no external dependencies. Here’s the structure at a glance.\nThe game loop. A requestAnimationFrame loop calls update(dt) and render() on every frame, where dt is the elapsed time in seconds (capped at 50ms to prevent physics explosions after tab switches). All movement and physics scale by dt, so the game runs at the same effective speed regardless of frame rate.\nAudio. There are no audio files — every sound is synthesized on the fly using the Web Audio API . Each effect is an OscillatorNode (usually a square wave for that 8-bit character) fed through a GainNode with a short volume envelope. The thrust sound uses a low-frequency oscillator (LFO) to wobble the carrier frequency, giving it that sputtering engine feel. All oscillators connect to a single masterGain node so pause and mute work cleanly without leaving any sounds dangling.\nThe push mechanic. This was the whole point of the exercise. When a bullet hits a ship, instead of destroying it, the code adds a velocity vector to the target in the bullet’s direction (pushVx, pushVy). That push velocity decays exponentially each frame (using Math.exp(-PUSH_DECAY * dt)), fading out over roughly two seconds. While a ship is being pushed it faces the push direction rather than the direction the player steered — a nice visual tell that something involuntary is happening. There’s also a kill-credit system: if a pushed ship dies while the push is still active, the shooter gets a 250-point bonus.\nUFOs that shoot back. I came up with a particularly nasty trick for the UFOs: shooting one doesn’t destroy it — it immediately turns and comes straight at you. The code computes the vector from the UFO to the shooter and sets the UFO’s velocity directly along that line at full speed. The practical effect is that a careless shot turns a wandering nuisance into a guided missile aimed at the person who fired. In a two-player game this creates a genuinely evil opportunity: bait your opponent into shooting a UFO, then watch it hunt them down.\nThe Blob. The enemy boss is a procedurally animated blobby shape. It’s drawn as a closed Bézier curve through a ring of 12 control points, each of which oscillates on …","date":1778284800,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1778358687,"objectID":"871b181d224e81d4d0843bba1de63ced","permalink":"https://mikejfromva.com/post/building-cosmic-blob-with-claude/","publishdate":"2026-05-09T00:00:00Z","relpermalink":"/post/building-cosmic-blob-with-claude/","section":"post","summary":"I used Claude Code to recreate Cosmic Glob — a two-player arcade game I used to type in by hand from a magazine on my Atari 130XE — as a browser-based canvas game called Cosmic Blob.","tags":["ai","gamedev","javascript","claude","retro"],"title":"Building Cosmic Blob with Claude","type":"post"},{"authors":null,"categories":null,"content":"Hey there, and welcome to my corner of the internet!\nI’m Mike Johnson, and I’ve decided to start this blog as a kind of public diary for my tech explorations. If you’ve stumbled across this site, you’re probably here because we’ve crossed paths somewhere in the software world, followed my link from LinkedIn, or maybe you’re just curious about what a lifelong technologist gets up to when curiosity strikes.\nWhat This Blog Is About I tend to post most often about programming languages and code—it’s where I live and breathe professionally—but my interests wander into interesting territories like quantum computing, cryptography, and computer architecture and assembly language. Think of this as my learning lab, written out loud. I’m approaching each topic with curiosity and a beginner’s mind, even after three decades in the field. Because that’s when the best learning happens.\nThe tone here will be casual and positive. No corporate speak, no pretending I have all the answers. Just genuine exploration, mistakes included.\nWhat Drives Me If you’re going to read my ramblings, you should probably know what makes me tick.\nMentorship matters to me. Throughout my career at places like Amazon, GEICO, Jefferson Lab, and Sun Microsystems, I’ve found that some of my proudest moments aren’t shipping features—they’re watching junior colleagues level up. When students or coworkers get unblocked and suddenly get it, that’s my favorite moment. I taught as adjunct faculty at Christopher Newport University for fourteen years, and my students knew they could always come to me for help, whether it was related to class or not. Some of my student reviews said I was “a total nerd” and “totally into geeking out”—guilty as charged. Others said I was “always happy to help outside of the class, even if it’s not related to the course.” That’s exactly how I want to show up for people.\nCollaboration is everything. At work, I’m known for building bridges between teams. I assume good faith, share information freely, and genuinely want all teams to succeed together. Some of my best work has happened when I’ve helped connect the dots between groups that didn’t even know they needed each other.\nAlways learning. I’m endlessly curious, especially when it comes to science, math, and technology. Whether it’s diving deep into Rust and Go, listending to Stanford AI classes on YouTube, or bootstrapping new services in AWS, I want to understand not just how things work, but why. That curiosity has taken me from writing device drivers for Sun’s HPC systems to implementing Chinese cryptographic algorithms in AWS KMS to architecting PKI services at GEICO. Every problem is a chance to learn something new.\nScience is real. It feels strange that I need to say this in 2026 to anyone, anywhere, so much more so on an engineering site, but it’s both true and necessary. Science is the foundation of technology and engineering. Nobel-winning physics papers on quantum mechanics lead to better LED monitors. Discoveries in genomics and evolution lead to better vaccines and safer food supply chains. Mathematical proofs lead to new cryptographic algorithms and better security when browsing the Internet. But even when science gives us problems instead of solutions, it is equally real, and equally right. Global warming is an existential threat. Worldwide pandemics will decimate populations unless we improve vaccines, and, just as importantly, vaccination rates. Whether we like it or not, the world is a complex place. Luckily, scientists excel at understanding the complexities and sharing their knowledge with the rest of us.\nInclusion matters in engineering. If your organization lacks diversity, they are exluding valuable talent and overlooking opportunities to build a better team. One of the toughest places I ever worked was Amazon. And yet, even in a performance-driven division like Amazon Web Services, diversity and inclusion were essential in everything we did. Taking intentional actions towards including a more diverse population, by race, religion, gender, and sexuality, will improve the morale of your team and focus them more on finding solutions for tough problems.\nA Bit About Me I’ve been writing code professionally for thirty years, and honestly, I’m just getting started. My journey has taken me through some incredible places:\nI began my career at Jefferson Lab (Thomas Jefferson National Accelerator Facility), where I managed high-speed data acquisition systems for nuclear physics experiments and later developed control system components for particle accelerators. It was existing and cool to write code that helps scientists probe the fundamental nature of matter.\nAt Sun Microsystems, I worked on high-performance computing systems, creating benchmarks and instrumentation to squeeze every ounce of performance from parallel CPUs and distributed memory. I even contributed to HPC conference papers and authored research on scientific numerical library performance. The work …","date":1768780800,"expirydate":-62135596800,"kind":"page","lang":"en","lastmod":1780748859,"objectID":"b40beee07c09cea2c816f4b6d18639a0","permalink":"https://mikejfromva.com/post/welcome_to_my_blog/","publishdate":"2026-01-19T00:00:00Z","relpermalink":"/post/welcome_to_my_blog/","section":"post","summary":"An introduction to the blog and its author — a software engineer with thirty years of experience across Jefferson Lab, Sun Microsystems, Amazon, and GEICO, writing about programming languages, cryptography, general computing, and computer architecture.","tags":["personal","science"],"title":"Welcome To My Tech Journey","type":"post"}]