<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mike Hall</title>
    <description>Staff-level software engineer with expertise in Ruby, Rails, PostgreSQL, and scalable backend systems.</description>
    <link>https://www.just3ws.com/</link>
    <atom:link href="https://www.just3ws.com/rss.xml" rel="self" type="application/rss+xml" />
    <pubDate>Fri, 08 May 2026 00:44:08 -0500</pubDate>
    <lastBuildDate>Fri, 08 May 2026 00:44:08 -0500</lastBuildDate>
    <generator>Jekyll v4.3.4</generator>
    
      <item>
        <title>The Durable Insights of UGtastic: Shared Wisdom from the DevOps &amp; Craftsmanship Frontier</title>
        <description>&lt;p&gt;While digging through the UGtastic video archives to prepare them for republication, I’ve been struck by how many of these conversations—recorded over a decade ago—feel like they were scripted for today.&lt;/p&gt;

&lt;p&gt;Back in 2012-2014, we were at the “start” of two massive shifts: the &lt;strong&gt;DevOps movement&lt;/strong&gt; and the &lt;strong&gt;Software Craftsmanship movement&lt;/strong&gt;. At the time, we were debating how to bridge the gap between “Dev” and “Ops,” and whether “Craftsmanship” was just a fancy word for “doing your job well.”&lt;/p&gt;

&lt;p&gt;Re-reading these transcripts now, with the help of modern analysis, I’ve identified a series of what I call &lt;strong&gt;Durable Insights&lt;/strong&gt;. These aren’t just historical artifacts; they are high-confidence, high-impact principles that distilled complex technical and cultural ideas into punchy truths.&lt;/p&gt;

&lt;p&gt;Here is why I valued these interviews then, and why I’m sharing them again now.&lt;/p&gt;

&lt;h3 id=&quot;-the-human-high-bandwidth&quot;&gt;🎭 The Human High-Bandwidth&lt;/h3&gt;
&lt;p&gt;One of the most profound realizations from the archive is that while tools change, the human element of software is constant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/interviews/robert-martin-software-craftsmanship-north-america-2012/&quot;&gt;Robert “Uncle Bob” Martin&lt;/a&gt;&lt;/strong&gt; famously told me that the relationship between a speaker and an audience is like a &lt;strong&gt;“bartender and a patron.”&lt;/strong&gt; It’s a service-oriented interaction based on “filling the vessel.” In an era where we often consume technical knowledge through sterile AI summaries, Bob’s reminder that video is a “wide bandwidth” medium for emotion and personality is vital.&lt;/p&gt;

&lt;p&gt;Similarly, &lt;strong&gt;&lt;a href=&quot;/interviews/interview-with-hadi-hariri-general/&quot;&gt;Hadi Hariri&lt;/a&gt;&lt;/strong&gt; challenged the “introverted developer” myth, calling it a mask for communication friction. These were the early signals that “soft skills” were actually the “hardest skills” to master in a collaborative environment.&lt;/p&gt;

&lt;h3 id=&quot;️-strategic-architecture&quot;&gt;🏗️ Strategic Architecture&lt;/h3&gt;
&lt;p&gt;We often think of “modern” architecture as a post-cloud invention, but the foundations were laid in these interviews.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/interviews/camille-fournier-goto-conference-2014/&quot;&gt;Camille Fournier&lt;/a&gt;&lt;/strong&gt; provided a masterclass in pragmatism by reframing technical rewrites. They aren’t failures; they are &lt;strong&gt;strategic business decisions&lt;/strong&gt; based on the “maintenance tax.” This perspective is essential today as we navigate the transition from legacy monoliths to distributed, AI-augmented systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/interviews/jez-humble-goto-conference-2014/&quot;&gt;Jez Humble&lt;/a&gt;&lt;/strong&gt; was already defining DevOps not as a set of tools, but as a &lt;strong&gt;cultural movement&lt;/strong&gt; focused on continuous learning. Looking at where we are now, the teams that succeeded were the ones that took Jez’s cultural advice to heart, while those who just “bought a tool” are still struggling with the same handoff friction we discussed ten years ago.&lt;/p&gt;

&lt;h3 id=&quot;-the-art-of-practice&quot;&gt;💡 The Art of Practice&lt;/h3&gt;
&lt;p&gt;The Software Craftsmanship movement brought “practice” to the forefront. &lt;strong&gt;&lt;a href=&quot;/interviews/corey-haines-general/&quot;&gt;Corey Haines&lt;/a&gt;&lt;/strong&gt; introduced the “throwaway” constraint of the Code Retreat—deleting your code every 45 minutes to focus entirely on design.&lt;/p&gt;

&lt;p&gt;In our current era of AI-generated boilerplate, the value of &lt;strong&gt;internalized intuition&lt;/strong&gt; (what &lt;strong&gt;&lt;a href=&quot;/interviews/dave-thomas-goto-conference-and-community-goto-conference-and-community/&quot;&gt;Dave Thomas&lt;/a&gt;&lt;/strong&gt; calls “Unknown Knowns”) has never been higher. If we let the machines do all the thinking, we lose the “tacit knowledge” that only comes from deep, deliberate practice.&lt;/p&gt;

&lt;h3 id=&quot;-the-long-road-to-republication&quot;&gt;🤝 The Long Road to Republication&lt;/h3&gt;
&lt;p&gt;This project is deeply personal. I’ve wanted to get back to these archives for years, but the sheer volume of material made it a daunting task. It was only recently that modern AI tools enabled me to finally recover, transcribe, and analyze these hours of conversation.&lt;/p&gt;

&lt;p&gt;It is still very much a work in progress. While I’m retaining the original Vimeo links wherever possible, I am steadily migrating the entire library to YouTube. It’s a heavy lift that has taken a significant amount of time, and honestly, if I waited for every single video to be perfect, they would stay locked away for another decade. It has been long enough.&lt;/p&gt;

&lt;p&gt;So, please pardon the dust. You’ll find that some interviews are fully transcribed and analyzed, while others are still pending. Some early transcripts need a second pass to meet the quality standards I’m aiming for, but the process is finally coming together.&lt;/p&gt;

&lt;p&gt;Republishing these legacy videos isn’t just about nostalgia. It’s about &lt;strong&gt;continuity&lt;/strong&gt;. We often talk about “internet minutes” being the speed of our industry, but these durable insights prove that certain truths move much slower. They are the bedrock. By sharing what &lt;strong&gt;&lt;a href=&quot;/interviews/adrian-cockcroft-goto-conference-2014/&quot;&gt;Adrian Cockcroft&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;/interviews/interview-with-rebecca-parsons-goto-chicago-2015-general/&quot;&gt;Rebecca Parsons&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href=&quot;/interviews/avdi-grimm-general/&quot;&gt;Avdi Grimm&lt;/a&gt;&lt;/strong&gt; were talking about at the frontier, I want to bridge the gap for a new generation of developers entering a field that feels more chaotic than ever.&lt;/p&gt;

&lt;p&gt;I hope you enjoy watching these interviews from a “simpler time” in technology. I am profoundly grateful to every single person who took the time to sit down (or more often, stand) with me to discuss what excited them. They shared their work and their hope that others could take these lessons and build better products.&lt;/p&gt;

&lt;p&gt;The “Sound of Tokens” might be the new rhythmic backdrop of our work, but the wisdom in these archives remains the signal in the noise. Stay tuned—the process is in flight, and there is much more to come.&lt;/p&gt;
</description>
        <pubDate>Thu, 07 May 2026 00:00:00 -0500</pubDate>
        <link>https://www.just3ws.com/2026/05/07/the-durable-insights-of-ugtastic.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2026/05/07/the-durable-insights-of-ugtastic.html</guid>
        
        <category>Technical Strategy</category>
        
        <category>DevOps</category>
        
        <category>Software Craftsmanship</category>
        
        <category>Community</category>
        
        <category>UGtastic</category>
        
      </item>
    
      <item>
        <title>The Sound of Tokens: From 80&apos;s Arcades to the AI Era</title>
        <description>&lt;p&gt;It’s the 80’s and you’re an early adapter, young, impressionable, lacking life experience. You just stepped into an arcade, the cool kids place. The pressure is on. Money weighs heavy in your pocket. So many choices, possibilities. It feels great to be a kid.&lt;br /&gt;
You get in line to trade your $ you earned mowing neighbors’ yards. The machine dispenses tokens with a rapid and rhythmic sound. You will remember this sound for the rest of your life.&lt;br /&gt;
You step aside, count the tokens to make sure you got the correct amount. You are ready to begin. First available game or should I be more strategic? After all, not every game has the same reward. Some extend your life while select few give you tickets to redeem for a prize. Just in case, you walk by the glass cabinet to check out the prizes. You do rudimentary math in your head for that prize you want. You begin.&lt;br /&gt;
The goals are simple:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Beat the one with the highest score and your name/handle goes on the leader board, or&lt;/li&gt;
  &lt;li&gt;Get the tickets&lt;br /&gt;
It’s your first time, you’re going to do both, you never know which one will have a better outcome. The game is on and you’re in the midst of a critical point when message pops up: “insert token to continue”. You do. Repeat. You’re 5 tokens in. You’re lost in the game when a fleeting thought pops in. Should I try a different game? Yes. Skiball is next. You get bunch of tickets and count them in fervor. Did I get enough?&lt;br /&gt;
Eventually your tokens run out. You’re done, need to earn more to play more. You spent $10+, but at least you got a sticker and a piece of gum. You’re proud of yourself. Next time you’ll earn a Slinky.&lt;br /&gt;
Winning is exhilarating, so the process repeats for few weeks/months. Everyone at the arcade is all in. You’re among like minded people. Then 1 day your friend rolls into your driveway on a brand new bike. Not a baseline bike, the top tier one. It turns out his Dad is a part owner of that arcade you go to. The business is so good, your friend got the best bike there is. Eventually, he offers you a spin. You love it.&lt;br /&gt;
3+ decades later, you meet Claude. Hard not to, Claude is everywhere.&lt;br /&gt;
All the cool kids are doing it. You feel the surge of excitement again. You try it. Your Claude session ends on a cliff hanger - pay for a token to continue. Flashback. You know that feeling. This time, however, you don’t just empty your pockets, but the excitement is intoxicating. Everyone around you is shipping, winning and leaving the non-adapters behind.&lt;br /&gt;
You have a tool and you’re in search of a problem. Demonstrate work to market yourself. Pivot. Go, go, go. You keep seeing things differently, not because of the moral superiority, just experience Arcade taught you, the original “pay to win”. You proceed with caution, because you know what ROI is. Same game, new operator. You hope for everyone’s sake, they will at least get a sticker or bubble gum in the process. Learn all you can.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 04 Apr 2026 00:00:00 -0500</pubDate>
        <link>https://www.just3ws.com/2026/04/04/the-sound-of-tokens.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2026/04/04/the-sound-of-tokens.html</guid>
        
        <category>Technical Strategy</category>
        
        <category>AI</category>
        
        <category>ROI</category>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>🚀 From Y2K Panic to AI Anxiety: Why the Future is Always Worth Building</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-02-03-from-y2k-panic-to-ai-anxiety-why-the-future-is-always-worth-building.jpg&quot; alt=&quot;🚀 From Y2K Panic to AI Anxiety: Why the Future is Always Worth Building&quot;&gt;&lt;/figure&gt;

&lt;h3&gt; 1999: The World Braced for Collapse—But I Was Planning My Escape  &lt;/h3&gt;

&lt;p&gt; In &lt;strong&gt;December 1999&lt;/strong&gt;, the world was fixated on &lt;strong&gt;Y2K&lt;/strong&gt;. People feared that at the stroke of midnight, technology would fail—planes would fall from the sky, banks would lose all records, and the digital age would come crashing down.  &lt;/p&gt;

&lt;p&gt; But I wasn’t worried about Y2K. &lt;strong&gt;I was planning my own escape.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; I was working at my &lt;strong&gt;father’s shop&lt;/strong&gt;—unpaid, surviving on food and shelter, having to justify every dollar I asked for. My first real attempt at an IT career—a &lt;strong&gt;warehouse contract job assembling computers&lt;/strong&gt;—had come and gone. I was &lt;strong&gt;back where I started, with no money and no path forward.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; By the time Y2K hit, I wasn’t bracing for disaster. I was making my move.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Betting on the Future (Even When It’s Uncertain)  &lt;/h3&gt;

&lt;p&gt; I found an early &lt;strong&gt;CareerBuilder&lt;/strong&gt; job posting for a &lt;strong&gt;PC/Network Technician&lt;/strong&gt; at &lt;strong&gt;C.H. Robinson&lt;/strong&gt;. &lt;strong&gt;I didn’t meet all the requirements&lt;/strong&gt;, but I had:  &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Hands-on IT experience&lt;/strong&gt; from my short-lived contract job.  &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Freight forwarding knowledge&lt;/strong&gt; from working for my father.  &lt;/p&gt;

&lt;p&gt; C.H. Robinson was a &lt;strong&gt;freight company&lt;/strong&gt;, so I made my case:  &lt;/p&gt;

&lt;blockquote&gt; &lt;strong&gt;“I know the industry, and I know computers. I can learn the rest.”&lt;/strong&gt;  &lt;/blockquote&gt;

&lt;p&gt; That was enough. I got the job.  &lt;/p&gt;

&lt;p&gt; But taking the job &lt;strong&gt;came at a cost.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; When I told my &lt;strong&gt;mother&lt;/strong&gt; about the &lt;strong&gt;$42,000 salary&lt;/strong&gt;, she &lt;strong&gt;immediately told me to take it&lt;/strong&gt;—she would &lt;strong&gt;handle my father&lt;/strong&gt;. But when I told him, his response was simple:  &lt;/p&gt;

&lt;blockquote&gt; &lt;strong&gt;“You will come crawling back.”&lt;/strong&gt;  &lt;/blockquote&gt;

&lt;p&gt; He &lt;strong&gt;kicked me out&lt;/strong&gt;, gave me a &lt;strong&gt;deadline to leave&lt;/strong&gt;, and we didn’t talk for years.  &lt;/p&gt;

&lt;p&gt; I never crawled back. But I did return—&lt;strong&gt;on my terms&lt;/strong&gt;, standing alongside my then-girlfriend &lt;strong&gt;Aneta&lt;/strong&gt;, who would become my wife and my greatest supporter.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; 2025: The Future is Still Coming, and Fear Won’t Stop It  &lt;/h3&gt;

&lt;p&gt; Today, people fear &lt;strong&gt;AI&lt;/strong&gt; the way they feared &lt;strong&gt;Y2K&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; “It’s going to take all the jobs.” &lt;/li&gt; &lt;li&gt; “We’re losing control of technology.” &lt;/li&gt; &lt;li&gt; “We need to stop it before it’s too late.” &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; I understand the anxiety. But &lt;strong&gt;I feel the same way now that I did then&lt;/strong&gt;:  &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;There is no going back.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Staying in place is not an option.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;The only way forward is through.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; The lesson I learned in &lt;strong&gt;1999&lt;/strong&gt; is the same one I carry in &lt;strong&gt;2025&lt;/strong&gt;: &lt;strong&gt;The future is always uncertain, but it’s still worth building.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; Y2K didn’t end the world. AI won’t end the world either.  &lt;/p&gt;

&lt;p&gt; What we do &lt;strong&gt;right now&lt;/strong&gt;—how we &lt;strong&gt;adapt, learn, and build&lt;/strong&gt;—is what matters.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; What’s Your Y2K Moment?  &lt;/h3&gt;

&lt;p&gt; Have you ever faced &lt;strong&gt;a moment where everything felt uncertain, but you knew you had to move forward anyway?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; Drop a comment—I’d love to hear your story. 🚀  &lt;/p&gt;</description>
        <pubDate>Mon, 03 Feb 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/02/03/from-y2k-panic-to-ai-anxiety-why-the-future-is-always-worth-building.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/02/03/from-y2k-panic-to-ai-anxiety-why-the-future-is-always-worth-building.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>“They’re Your Legs.”</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-02-01-they-re-your-legs.jpg&quot; alt=&quot;“They’re Your Legs.”&quot;&gt;&lt;/figure&gt;

&lt;p&gt; A few weeks ago, I was at Valvoline getting an oil change.  &lt;/p&gt;

&lt;p&gt; It was a busy day—&lt;strong&gt;full bays, a strong shop lead keeping things moving, and a small crew working fast.&lt;/strong&gt; Watching them coordinate, I was impressed. I was enjoying the moment so much that I even agreed to buy an air filter replacement—something I usually do myself.  &lt;/p&gt;

&lt;p&gt; My car was due for a tire rotation, so I stepped out while they lifted it.  &lt;/p&gt;

&lt;p&gt; The manager helped the younger mechanics &lt;strong&gt;stabilize the lift, ensuring it was locked in place before moving to the next car.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; Everything looked good.  &lt;/p&gt;

&lt;p&gt; And then—&lt;strong&gt;I saw it.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; One of the mechanics sat &lt;strong&gt;cross-legged under the rear axle.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; 🚨 &lt;strong&gt;My dad’s voice hit me before I even realized I was moving.&lt;/strong&gt; 🚨  &lt;/p&gt;

&lt;p&gt; I was through the door. &lt;strong&gt;“Hey, don’t cross bones. Don’t trust that jack.”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; The young mechanic looked up. “I’m okay,” he said.  &lt;/p&gt;

&lt;p&gt; I just shrugged. &lt;strong&gt;“Okay. They’re your legs.”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; And he moved back.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; A Team Owns Its Own Safety  &lt;/h3&gt;

&lt;p&gt; Once they were done, I spoke with two of the younger mechanics—a &lt;strong&gt;young man who had been working on my car and a young woman who had been listening in as she finished her task.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; I reminded them about their buddy—the one who &lt;strong&gt;hand-waved&lt;/strong&gt; his safety, the one who thought &lt;strong&gt;he’d be fine under the axle.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; I told them:  &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Kneeling might be uncomfortable.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; 🚨 &lt;strong&gt;But it’s a lot more comfortable than getting crushed.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; And more importantly—&lt;strong&gt;his safety is their problem, too.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; If he gets pinned, it won’t just be &lt;strong&gt;his&lt;/strong&gt; crisis. &lt;strong&gt;It’ll be theirs.&lt;/strong&gt; It’ll be &lt;strong&gt;them&lt;/strong&gt; trying to save him. It’ll be &lt;strong&gt;them&lt;/strong&gt; listening to the screams.  &lt;/p&gt;

&lt;p&gt; Because a team isn’t just responsible for their own safety. &lt;strong&gt;They’re responsible for making sure everyone makes it home.&lt;/strong&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; I Grew Up in a Shop. I Know What Happens When You Get It Wrong.  &lt;/h3&gt;

&lt;p&gt; I grew up in a shop. My father was a &lt;strong&gt;lead diesel mechanic and later an owner-operator. Keeping him on the road was priority number one.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; By 13, I was &lt;strong&gt;breaking down truck tires, armed with nothing but a breaker bar and the will to get it done.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; By my late teens, I was running the yard while my dad was on the road. &lt;strong&gt;When he came back, he’d tell me what needed to be done, then go to sleep so he could get back on the highway.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; That meant I had to work &lt;strong&gt;alone&lt;/strong&gt;—late at night, in a steel building, with machines that didn’t care if I lived or died.  &lt;/p&gt;

&lt;p&gt; &lt;strong&gt;There was no room for mistakes.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; 🛠 &lt;strong&gt;I had to know how to be safe—because no one was there to save me if I wasn’t.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; 🛠 &lt;strong&gt;I had to respect the work—because there’s no such thing as &quot;I’ll fix it later&quot; when you’re under 80,000 pounds of steel.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; My dad drilled it into me:  &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Never trust a jack.&lt;/strong&gt; Always &lt;strong&gt;block and chock.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Assume everything is heavier, sharper, and more dangerous than it looks.&lt;/strong&gt;   &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Know the difference between discomfort and disaster.&lt;/strong&gt; A little discomfort today beats a lifetime of regret.   &lt;/p&gt;

&lt;p&gt; ✅ &lt;strong&gt;Never rush safety.&lt;/strong&gt; You’ll never get back the time you lose if you get it wrong.  &lt;/p&gt;

&lt;p&gt; The lesson was clear:  &lt;/p&gt;

&lt;p&gt; 👉 &lt;strong&gt;The best way to learn safety isn’t through experience—it’s through listening to those who already have it.&lt;/strong&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; This Moment Meant Something.  &lt;/h3&gt;

&lt;p&gt; As I got into my car, I called out— &lt;strong&gt;“Hey, stay safe.”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; And he hollered back— &lt;strong&gt;“I will.”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; That moment stuck with me.  &lt;/p&gt;

&lt;p&gt; I was raised to be independent. To survive. But when it comes to safety, no one is truly alone—it’s always a shared responsibility.  &lt;/p&gt;

&lt;p&gt; Today, &lt;strong&gt;I’m not the kid in the shop anymore.&lt;/strong&gt; I’m older. A professional software engineer. My world today is almost unimaginable to that younger version of me.  &lt;/p&gt;

&lt;p&gt; But when I see someone who reminds me of &lt;strong&gt;the kid I used to be?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; I can’t walk away without making sure &lt;strong&gt;they know what I know.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; Because sometimes, that’s the difference between &lt;strong&gt;walking away from the job at the end of the day—&lt;/strong&gt; And &lt;strong&gt;not walking at all.&lt;/strong&gt;  &lt;/p&gt;</description>
        <pubDate>Sat, 01 Feb 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/02/01/they-re-your-legs.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/02/01/they-re-your-legs.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>The Boy Who Told the Truth</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-02-01-the-boy-who-told-the-truth.jpg&quot; alt=&quot;The Boy Who Told the Truth&quot;&gt;&lt;/figure&gt;

&lt;p&gt; There was a boy who saw a wolf.  &lt;/p&gt;

&lt;p&gt; He was a shepherd, living where the wild met the edges of civilization. His job was simple: protect the flock, watch the hills, and warn the village if danger came.  &lt;/p&gt;

&lt;p&gt; One day, he saw the shadow of a wolf in the distance. He shouted to the village: &lt;strong&gt;“A wolf is coming!”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; By the time the villagers arrived, the wolf was gone. They saw nothing, shrugged, and walked back home.  &lt;/p&gt;

&lt;p&gt; The boy, still uneasy, began reinforcing the fences, setting traps, and watching the darkness more carefully.  &lt;/p&gt;

&lt;p&gt; The next day, he saw it again—closer this time. He called out once more: &lt;strong&gt;“The wolf is coming!”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; Again, the villagers arrived too late. And now, they were annoyed.  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;Stop being so dramatic,&quot;&lt;/em&gt; they said. &lt;em&gt;&quot;Why are you always making noise?&quot;&lt;/em&gt; &lt;em&gt;&quot;If the wolf was real, we would have seen it too.&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; The boy wanted them to understand—this was not imagination. He wasn’t calling for fun. He was calling because he lived at the edge, where the safety of the village ended, and reality began.  &lt;/p&gt;

&lt;p&gt; But the villagers had always been safe. To them, safety was normal. The idea of a wolf coming wasn’t real &lt;strong&gt;because it had never happened to them.&lt;/strong&gt;  &lt;/p&gt;

&lt;h3&gt; The Wolf Comes Anyway  &lt;/h3&gt;

&lt;p&gt; One night, the boy saw the wolf slip through the trees and attack his sheep. He ran to the village, desperate, shouting louder than ever before. &lt;strong&gt;“The wolf is here!”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; The villagers, tired of his warnings, &lt;strong&gt;did nothing.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; By morning, the wolf had not only slaughtered the flock—it had entered the village. The villagers, unprepared, finally understood the danger. But it was too late.  &lt;/p&gt;

&lt;h3&gt; Who Do They Blame?  &lt;/h3&gt;

&lt;p&gt; Not themselves.  &lt;/p&gt;

&lt;p&gt; Not their complacency.  &lt;/p&gt;

&lt;p&gt; Not the false security of their village walls.  &lt;/p&gt;

&lt;p&gt; They blame the boy.  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;Why didn’t you warn us better?&quot;&lt;/em&gt; &lt;em&gt;&quot;You should have told us in a way that made us listen.&quot;&lt;/em&gt; &lt;em&gt;&quot;You were too emotional about it—no wonder we didn’t take you seriously.&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; The boy, exhausted, wounded, and furious, stared at them in disbelief.  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;I told you,&quot;&lt;/em&gt; he whispered. &lt;em&gt;&quot;You just didn’t want to hear it.&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Real Lesson of The Boy Who Cried Wolf  &lt;/h3&gt;

&lt;p&gt; People misremember &lt;em&gt;The Boy Who Cried Wolf&lt;/em&gt; as a story about honesty. But &lt;strong&gt;what if the boy was never lying?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; What if the real problem was &lt;strong&gt;not urgency, but apathy&lt;/strong&gt;?  &lt;/p&gt;

&lt;p&gt; This happens everywhere.  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; The &lt;strong&gt;engineer&lt;/strong&gt; who warns that the system is vulnerable. &lt;/li&gt; &lt;li&gt; The &lt;strong&gt;scientist&lt;/strong&gt; who warns of environmental collapse. &lt;/li&gt; &lt;li&gt; The &lt;strong&gt;security expert&lt;/strong&gt; who sees the breach before it happens. &lt;/li&gt; &lt;li&gt; The &lt;strong&gt;worker&lt;/strong&gt; who calls out a toxic leader before the damage spreads. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; They see the wolf first. They warn the village. And instead of listening, the village argues about &lt;strong&gt;tone&lt;/strong&gt;, about &lt;strong&gt;proof&lt;/strong&gt;, about how the warning makes them &lt;strong&gt;feel&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt; By the time the wolf arrives, the damage is done.  &lt;/p&gt;

&lt;p&gt; And the worst part? The people who dismissed the warning will never admit fault. They’ll blame the messenger. They’ll say, &lt;em&gt;&quot;If you had only warned us in the right way, we would have listened.&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; But that’s a lie.  &lt;/p&gt;

&lt;p&gt; They didn’t listen &lt;strong&gt;because they didn’t want to.&lt;/strong&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; When Someone Warns You About the Wolf, Listen.  &lt;/h3&gt;

&lt;p&gt; If someone is raising alarms—especially someone at the edge of the problem—&lt;strong&gt;don’t ignore them just because you don’t feel the danger yet.&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt;&lt;strong&gt;Listen to the people closest to the problem.&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Don’t dismiss warnings just because they don’t sound the way you want them to.&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Don’t wait until the wolf is at your door to take it seriously.&lt;/strong&gt;&lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; Because when that happens, it’s not just the boy who pays the price.  &lt;/p&gt;

&lt;p&gt; It’s the whole village.  &lt;/p&gt;</description>
        <pubDate>Sat, 01 Feb 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/02/01/the-boy-who-told-the-truth.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/02/01/the-boy-who-told-the-truth.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>A Moment of Absurdity in Stagnation</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-31-a-moment-of-absurdity-in-stagnation.jpg&quot; alt=&quot;A Moment of Absurdity in Stagnation&quot;&gt;&lt;/figure&gt;

&lt;p&gt; In the early 2000s, before .NET had solidified and JavaScript was still dismissed as a “toy language,” I worked at a small firm developing &lt;strong&gt;kiosk-based HR systems&lt;/strong&gt;. The company was a skeleton crew—just the owner, a senior developer with a long corporate background, a part-time contractor, and me. The entire technology stack was &lt;strong&gt;VBScript, ASP, ActiveX, and IE6&lt;/strong&gt;, dictated by a belief that &lt;strong&gt;staying deeply embedded in Microsoft’s ecosystem was the only “serious” way forward.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt; One of my projects was an &lt;strong&gt;on-screen keyboard generator&lt;/strong&gt;. The initial version in &lt;strong&gt;VBScript&lt;/strong&gt; was bulky and slow, so I rewrote it in &lt;strong&gt;JavaScript&lt;/strong&gt;, dramatically improving speed and maintainability. The next day, I was written up. Not because the solution didn’t work—it did—but because &lt;strong&gt;I had violated an unspoken rule&lt;/strong&gt;. JavaScript was forbidden. It was, according to the senior developer, a “toy language,” and more people knew VBScript anyway.  &lt;/p&gt;

&lt;p&gt; I sat across from him in the owner’s &lt;strong&gt;empty office&lt;/strong&gt;, as he placed the write-up on the desk in front of me, taking the owner’s chair as if staging a corporate tribunal. The absurdity of the moment hit me then—&lt;strong&gt;he had no one but me and a part-time contractor to rely on. He depended on me entirely.&lt;/strong&gt; Yet, here we were, engaged in a theater of control over something as trivial as which scripting language was used to accomplish the task.  &lt;/p&gt;

&lt;p&gt; This pattern repeated when &lt;strong&gt;.NET&lt;/strong&gt; entered the conversation. I suggested we explore it. The contractor agreed. But the senior developer shot it down without discussion. When the company’s &lt;strong&gt;one major client fell through&lt;/strong&gt;, a potential buyout followed—only to collapse once the buyer realized the technology stack was already obsolete.  &lt;/p&gt;

&lt;p&gt; The company folded soon after.  &lt;/p&gt;

&lt;p&gt; In retrospect, that moment in the &lt;strong&gt;empty office&lt;/strong&gt; encapsulated the entire downfall. A leader so preoccupied with controlling the present that he was blind to the future. So certain of his authority that he refused to see &lt;strong&gt;the walls closing in around him&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt; I walked away from that experience with a simple lesson: &lt;strong&gt;sometimes, the greatest risk isn’t change—it’s refusing to change.&lt;/strong&gt;  &lt;/p&gt;</description>
        <pubDate>Fri, 31 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/31/a-moment-of-absurdity-in-stagnation.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/31/a-moment-of-absurdity-in-stagnation.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>The Sound Above: Bridging Inspiration and Understanding in Tech</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-24-the-sound-above-bridging-inspiration-and-understanding-in-tech.jpg&quot; alt=&quot;The Sound Above: Bridging Inspiration and Understanding in Tech&quot;&gt;&lt;/figure&gt;

&lt;h3&gt; Defining the Sound Above  &lt;/h3&gt;

&lt;p&gt; “The sound above” represents the echoes of ideas, inspirations, and cultural touchstones that have shaped an industry or a mindset. It’s the legacy carried forward by those who came before, forming an unspoken language and shared context among those who lived through it. For many in tech, &lt;em&gt;Star Trek&lt;/em&gt; is part of that sound—a source of optimism, imagination, and exploration that inspired entire generations of programmers, engineers, and dreamers.  &lt;/p&gt;

&lt;p&gt; But as time passes, the sound grows faint for those who didn’t grow up hearing it. To them, it’s not inspiration; it’s noise—opaque references that can feel like barriers instead of bridges.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Star Trek and the Foundation of Tech  &lt;/h3&gt;

&lt;p&gt; &lt;em&gt;Star Trek&lt;/em&gt;, especially &lt;em&gt;The Next Generation&lt;/em&gt;, holds a special place in the hearts of many who shaped the modern tech industry. The show’s vision of a future driven by exploration, collaboration, and technology as a force for good resonated deeply with the pioneers of computing. Episodes like &lt;em&gt;“Darmok”&lt;/em&gt; embody the spirit of problem-solving, communication, and empathy—core values that underpin not just technology but how we work together as people.  &lt;/p&gt;

&lt;p&gt; In &lt;em&gt;Darmok&lt;/em&gt;, Captain Picard faces an impossible situation: the Tamarians speak entirely in metaphor, referencing their own history and culture in ways that are incomprehensible to outsiders. It’s only through shared struggle, patience, and a willingness to learn that Picard bridges the gap, finding connection where it seemed impossible. This is the heart of what &lt;em&gt;Star Trek&lt;/em&gt; has always been—a lesson in overcoming differences through empathy, intellect, and collaboration.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The New Generation: A Different Sound  &lt;/h3&gt;

&lt;p&gt; For those entering tech today, &lt;em&gt;Star Trek&lt;/em&gt; isn’t the foundation—it’s a distant echo. To many, it’s just another cultural reference they’re expected to decode, one more hoop to jump through in an industry that already feels intimidating. It’s easy for them to see it as exclusionary, a marker of an in-group they’re not part of. And they’re not wrong—without context, a &lt;em&gt;Star Trek&lt;/em&gt; reference might as well be Smurf language: familiar to some, meaningless to others.  &lt;/p&gt;

&lt;p&gt; But what they may not see—and what senior leaders must help them see—is that &lt;em&gt;Star Trek&lt;/em&gt; isn’t just a reference; it’s part of the sound above. It reflects the values and hopes of its time, just as today’s inspirations will shape the next generation of innovators. The task isn’t to force newcomers to learn &lt;em&gt;Star Trek&lt;/em&gt; or pass a cultural test—it’s to build a bridge between what inspired us and what inspires them, so they too can contribute to the sound.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Challenge for Seniors: From Sound to Connection  &lt;/h3&gt;

&lt;p&gt; As senior members of the tech industry, it’s our responsibility to adapt how we communicate and lead. We can’t assume that our references will automatically resonate with others. Instead, we must respect that new people bring their own inspirations, references, and perspectives—and that the gap isn’t a failure on their part. It’s an opportunity for us to connect.  &lt;/p&gt;

&lt;p&gt; The way forward is through empathy:   &lt;/p&gt;

&lt;ol&gt; &lt;li&gt; &lt;strong&gt;Be Receptive&lt;/strong&gt;: Understand that new voices aren’t rejecting the past; they’re starting from a different place. Meet them where they are. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Respect Their Inspirations&lt;/strong&gt;: What inspires them might not look like &lt;em&gt;Star Trek&lt;/em&gt;, and that’s okay. Their references are no less valid. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Build Bridges&lt;/strong&gt;: Share the sound above, not as a requirement, but as a gift. Show how the echoes of &lt;em&gt;Star Trek&lt;/em&gt;—its optimism, its lessons in connection, its problem-solving spirit—can still inspire, but only if we make it accessible. &lt;/li&gt; &lt;/ol&gt;

&lt;hr&gt;

&lt;h3&gt; Why It Matters  &lt;/h3&gt;

&lt;p&gt; The industry’s strength has always been its ability to build on what came before. But that only works if the foundation is shared. If we want the next generation to care about the sound above—to find inspiration in the values and stories that shaped us—we must first help them thrive. Only then can we inspire them to look up, to hear the echoes of the past and add their own notes to the sound of the future.  &lt;/p&gt;

&lt;p&gt; In the end, it’s not about forcing people to learn &lt;em&gt;Star Trek&lt;/em&gt;. It’s about showing them why it matters to us, and why it might matter to them, too. Just as Picard found a way to connect with the Tamarians, we must find a way to connect across the gaps of generations, culture, and experience. That’s the true spirit of &lt;em&gt;Star Trek&lt;/em&gt;—to boldly go where understanding can be built.  &lt;/p&gt;</description>
        <pubDate>Fri, 24 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/24/the-sound-above-bridging-inspiration-and-understanding-in-tech.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/24/the-sound-above-bridging-inspiration-and-understanding-in-tech.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>The Power of People, Not Just AI</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-21-the-power-of-people-not-just-ai.jpg&quot; alt=&quot;The Power of People, Not Just AI&quot;&gt;&lt;/figure&gt;

&lt;p&gt; In an era where AI dominates conversations and headlines, it’s easy to feel like the future of work is all about machines solving problems for us. But the truth is simpler—and far more human.  &lt;/p&gt;

&lt;p&gt; At its core, the work we do is still about people coming together to solve complex problems. And while AI has its place in that story, the most transformative changes I’ve seen are rooted in something profoundly human: &lt;strong&gt;collaboration, understanding, and connection.&lt;/strong&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; OpenTelemetry: A Catalyst for Change  &lt;/h3&gt;

&lt;p&gt; For me, OpenTelemetry (OTel) has been one of the most powerful tools for driving these changes—not just as a technical solution, but as a cultural and collaborative one.  &lt;/p&gt;

&lt;p&gt; OTel provides a framework for observability, enabling teams to measure, understand, and improve their systems. But its real value lies in how it brings people together:  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; &lt;strong&gt;Conversations spark between teams&lt;/strong&gt; that may never have collaborated before. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Silos begin to connect&lt;/strong&gt;, as shared dependencies and goals come into focus. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Insights surface&lt;/strong&gt; into the challenges and triumphs of other teams’ work, creating empathy and understanding across the organization. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; The journey to system observability isn’t easy, and it’s far from complete. But even at this early stage, the impact is undeniable.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Human Impact of Observability  &lt;/h3&gt;

&lt;p&gt; When we introduced observability, I didn’t just see better metrics or cleaner dashboards—I saw people talking.  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; Teams that were once isolated began collaborating. &lt;/li&gt; &lt;li&gt; Challenges that had been hidden in the complexity of our systems became apparent—and discussable. &lt;/li&gt; &lt;li&gt; Contributors found new ways to align their efforts, building not just better systems, but better relationships. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; This is the real value of OpenTelemetry. It’s a practical driver of technical conversations that are inclusive and empowering. And because it’s built on shared frameworks and standards, the innovation it sparks is &lt;strong&gt;empirically provable and wholly owned by the people doing the work.&lt;/strong&gt;  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; AI’s Role in the Story  &lt;/h3&gt;

&lt;p&gt; AI certainly has its place, and it can help us solve certain types of problems faster or more effectively. But when it comes to the complexity of understanding our systems—and, more importantly, the people behind them—there’s no substitute for human connection.  &lt;/p&gt;

&lt;p&gt; OpenTelemetry shows us what’s possible when we focus on creating the conditions for collaboration. It’s not just a technical initiative; it’s a cultural shift, a spark for meaningful, distributed change that connects people across silos and teams.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Starting the Journey  &lt;/h3&gt;

&lt;p&gt; We’re still in the early stages of this journey. Observability isn’t perfect, and the work isn’t 100% done. But the act of starting—of creating a shared framework and encouraging collaboration—has already shown how much we can achieve together.  &lt;/p&gt;

&lt;p&gt; The challenges of complex systems, siloed teams, and competing priorities are daunting. But OpenTelemetry has proven that even the smallest steps toward understanding can unlock meaningful change.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; A Call to Action  &lt;/h3&gt;

&lt;p&gt; The future isn’t just about AI. It’s about &lt;strong&gt;people, working together to solve hard problems.&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; It’s about creating frameworks that enable connection. &lt;/li&gt; &lt;li&gt; It’s about breaking down silos and fostering collaboration. &lt;/li&gt; &lt;li&gt; And it’s about starting the conversations that lead to real, lasting innovation. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; If you’re considering a journey toward observability, don’t wait for perfection. The act of starting is enough to make a difference—not just for your systems, but for your people.  &lt;/p&gt;</description>
        <pubDate>Tue, 21 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/21/the-power-of-people-not-just-ai.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/21/the-power-of-people-not-just-ai.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>What I Learned from Running Down a Hallway with Groupon&apos;s CEO</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-18-what-i-learned-from-running-down-a-hallway-with-groupon-s-ceo.jpg&quot; alt=&quot;What I Learned from Running Down a Hallway with Groupon&apos;s CEO&quot;&gt;&lt;/figure&gt;

&lt;p&gt; Sometimes, a single question can change everything. For me, it wasn’t just a question—it was also a hallway run with Andrew Mason, Groupon’s CEO at the time, that shifted the trajectory of my career and taught me lessons I’m still unpacking to this day.  &lt;/p&gt;

&lt;p&gt; It started with a lunch that almost didn’t happen. Our engineering team had been scheduled to meet Andrew for months, but the meeting kept getting rebooked. By the time it finally happened, most of our team was at a conference, leaving just a few of us behind. We assumed the lunch would be postponed again, but it wasn’t. Nervously, a small group of us sat down in a meeting room, unsure what to expect.  &lt;/p&gt;

&lt;p&gt; As we waited, we saw Andrew approach through the glass walls of the office. He glanced in, did a double take, consulted with his assistant, and hesitated for a moment. I’ll never forget that moment of hesitation—it was as if he was deciding whether this meeting was worth his time. Then, he shrugged, walked in, and greeted us enthusiastically.  &lt;/p&gt;

&lt;p&gt; That decision—to step into a meeting with a smaller group than expected—would end up being pivotal for me, though I didn’t know it yet.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Question That Changed Everything  &lt;/h3&gt;

&lt;p&gt; The lunch was casual, filled with sushi and light conversation about engineering culture and corporate vision. Toward the end, Andrew asked if we had any questions. I hesitated, then decided to speak up:  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;Are you aware of the current attrition rate?&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; Andrew was surprised but thoughtful. His initial answer—that attrition was within industry norms—wasn’t unexpected. But I followed up:  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;Does that account for who is leaving?&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; I pointed out that many of our most skilled and experienced engineers—those who had been with Groupon from the earliest days—were leaving.  &lt;/p&gt;

&lt;p&gt; Andrew didn’t dismiss the question. He considered it and said he’d look into it. The lunch wrapped up shortly after, and I figured that was the end of it.  &lt;/p&gt;

&lt;p&gt; But it wasn’t.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Hallway Run  &lt;/h3&gt;

&lt;p&gt; As I walked back to my desk, I heard someone call out: &lt;em&gt;&quot;Hey, hey, what’s your name?&quot;&lt;/em&gt; I turned to see Andrew running down the hallway toward me. He was out of breath by the time he reached me, but he didn’t care about the stares from passing employees. He motioned for me to follow him.  &lt;/p&gt;

&lt;p&gt; We ran through the office—me, completely bewildered, and Andrew, completely unfazed. Eventually, we arrived at an open-plan intersection where a group of people were deep in conversation with Brian, who was essentially head of engineering. Andrew, still catching his breath, didn’t hesitate to interrupt.  &lt;/p&gt;

&lt;p&gt; &lt;em&gt;&quot;Mike, this is Brian. Brian, this is Mike. Mike, tell Brian everything you just told me.&quot;&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; And then he ran off, leaving me standing there, completely stunned, in the middle of the intersection with Brian and half a dozen others who had clearly been in the middle of something important.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Moment That Changed Everything  &lt;/h3&gt;

&lt;p&gt; That moment was life-altering for me, though it likely wasn’t a big deal for Andrew. At the height of Groupon, with millions of things vying for his attention, he heard something I said and decided it mattered enough to act on immediately.  &lt;/p&gt;

&lt;p&gt; For me, it was overwhelming. At the time, I didn’t fully understand the weight of what had just happened. It was like being hit by a really cool car in an entirely unexpected circumstance—not something I planned for, but something I couldn’t ignore.  &lt;/p&gt;

&lt;p&gt; That conversation led to a new role as the &quot;Talent Development Business Partner for Engineering,&quot; a role I could never have imagined for myself when I first began transitioning into software development.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; More Than I Thought Possible  &lt;/h3&gt;

&lt;p&gt; When I took my first timid steps into this new phase of my career, I struggled to believe I was worthy to work with the brilliant minds of Obtiva, let alone play any meaningful role in a company like Groupon. I thought being a Software Developer would be more than enough—that just reaching that point was my goal.  &lt;/p&gt;

&lt;p&gt; But this moment, this role, this responsibility—it was so much more than I could have imagined. And, honestly, it was more than I could bear at the time. I didn’t feel ready to be &quot;more.&quot; It was intimidating to step into something so far beyond what I thought was possible for me.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Leadership Lesson  &lt;/h3&gt;

&lt;p&gt; That experience taught me a profound lesson about leadership: the further you are from the day-to-day realities of your employees, the harder it becomes to recover when you lose their trust or perspective.  &lt;/p&gt;

&lt;p&gt; Attrition isn’t just a metric; it’s a story. When you look at who is leaving, you begin to understand the unspoken dynamics shaping your organization.  &lt;/p&gt;

&lt;p&gt; Andrew didn’t just listen—he acted. That’s the part I reflect on most often. Listening is one thing, but acting before the moment passes you by is what makes the difference.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Why This Matters Now  &lt;/h3&gt;

&lt;p&gt; Organizations often talk about transformation, innovation, and growth. But none of those are possible without the people who make them happen. If you’re in a leadership position, I encourage you to ask yourself: &lt;em&gt;What am I missing? Who should I be listening to? What action can I take today to bridge the gap between strategy and experience?&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt; Sometimes, listening means sitting down over sushi. Other times, it means running down a hallway. Either way, it means acting when the opportunity presents itself—even if it’s unexpected.  &lt;/p&gt;</description>
        <pubDate>Sat, 18 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/18/what-i-learned-from-running-down-a-hallway-with-groupon-s-ceo.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/18/what-i-learned-from-running-down-a-hallway-with-groupon-s-ceo.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>The Power of Titles: What I Misunderstood</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-14-the-power-of-titles-what-i-misunderstood.jpg&quot; alt=&quot;The Power of Titles: What I Misunderstood&quot;&gt;&lt;/figure&gt;

&lt;p&gt; For most of my career, I’ve eschewed titles. I saw people chase them like prizes—coveting authority without earning respect, collecting accolades without delivering results. I didn’t want to be like that. I thought my work should speak for itself, that my results would be my title.  &lt;/p&gt;

&lt;p&gt; But that was my mistake.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; What I Misunderstood About Titles  &lt;/h3&gt;

&lt;p&gt; I thought rejecting titles meant rejecting ego, politics, and posturing. What I didn’t realize was that titles aren’t just symbols of power—they’re tools of utility. They’re shorthand for your role, your value, and your expertise in a world where time is scarce and perceptions matter.  &lt;/p&gt;

&lt;p&gt; Here’s what I misunderstood:  &lt;/p&gt;

&lt;ol&gt; &lt;li&gt; &lt;strong&gt;Titles Shape Perception&lt;/strong&gt; A title can mean the difference between being invited to the table or left outside the room. It doesn’t matter if you’re the most qualified person in the building—if your role doesn’t reflect that, people won’t know to include you. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Titles Signal Authority&lt;/strong&gt; Titles grant weight to your voice. Without them, even your best ideas can be dismissed or overlooked—not because they lack merit, but because people instinctively defer to perceived authority. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Titles Protect Your Work&lt;/strong&gt; A title isn’t just about status; it’s about accountability. When your role is clearly defined and respected, it’s harder for others to co-opt your contributions or sideline your expertise. &lt;/li&gt; &lt;/ol&gt;

&lt;hr&gt;

&lt;h3&gt; Why I Avoided Titles  &lt;/h3&gt;

&lt;p&gt; I avoided titles because of what I’d seen them represent:  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; People chasing promotions for the sake of appearances. &lt;/li&gt; &lt;li&gt; Colleagues using their titles as shields to deflect accountability. &lt;/li&gt; &lt;li&gt; Leaders wielding authority without the competence to back it up. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; To me, titles seemed like distractions from what really mattered: the work. But I failed to see the bigger picture.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; What I’ve Learned About Utility  &lt;/h3&gt;

&lt;p&gt; Titles aren’t inherently good or bad—it’s what you do with them that matters. For someone like me, who values integrity, collaboration, and results, a title isn’t about ego. It’s about utility. It’s about:  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt;&lt;strong&gt;Making your contributions visible.&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Amplifying your voice.&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Ensuring your seat at the table.&lt;/strong&gt;&lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; A title is a tool—not a prize. And in rejecting it, I gave others tools to define me, to speak over me, and to take credit for work they didn’t do.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Moving Forward  &lt;/h3&gt;

&lt;p&gt; I still don’t covet titles. But I no longer reject them outright. I recognize their utility—not as symbols of status, but as tools for impact. Titles aren’t about what they mean to &lt;em&gt;me&lt;/em&gt;; they’re about what they signal to others. They’re a key to opening doors, shaping conversations, and protecting the value I bring to the table.  &lt;/p&gt;

&lt;p&gt; So no, I don’t want your job. But I do want the recognition and respect that come with doing it well. Titles can help me achieve that—not for vanity, but for fairness. That’s not a mistake I’ll make again.  &lt;/p&gt;</description>
        <pubDate>Tue, 14 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/14/the-power-of-titles-what-i-misunderstood.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/14/the-power-of-titles-what-i-misunderstood.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>The Dog Who Caught Their Tail: The Best Collaborators I&apos;ve Worked With</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-14-the-dog-who-caught-their-tail-the-best-collaborators-i-ve-worked-with.jpg&quot; alt=&quot;The Dog Who Caught Their Tail: The Best Collaborators I&apos;ve Worked With&quot;&gt;&lt;/figure&gt;

&lt;p&gt; Some people step into new roles like a dog catching its tail—they’ve achieved something they’ve worked hard for, but the real test comes after the title. Among the best collaborators I’ve worked with are those who make this transition not just about themselves, but about the people around them. They don’t just take on responsibility; they elevate everyone involved.  &lt;/p&gt;

&lt;p&gt; This isn’t about avoiding mistakes—it’s about embracing growth and collaboration. These are the traits that make someone truly great to work with.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Strengths of Outstanding Leaders  &lt;/h3&gt;

&lt;p&gt; The best people in new roles have a way of turning potential vulnerabilities into opportunities for connection. They do this by focusing on a few key behaviors:  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; &lt;strong&gt;Sharing Context:&lt;/strong&gt; They understand that information is most valuable when it’s shared. Instead of hoarding knowledge, they ensure everyone is aligned and equipped to contribute meaningfully. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Seeking Input:&lt;/strong&gt; They’re not afraid to admit they don’t know everything. By inviting perspectives, they build trust and create space for better solutions. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Celebrating Collaboration:&lt;/strong&gt; They recognize that working with others isn’t a weakness—it’s the key to collective success. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; These behaviors build trust, foster innovation, and make collaboration not just productive but genuinely enjoyable.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Impact of Great Collaborators  &lt;/h3&gt;

&lt;p&gt; When someone approaches leadership with humility and openness, it transforms the way teams function. Here’s what I’ve noticed about the best collaborators:  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; &lt;strong&gt;They Remove Obstacles:&lt;/strong&gt; By sharing context and being transparent, they make it easier for everyone to do their best work. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;They Build Trust:&lt;/strong&gt; Open communication creates an environment where people feel safe to share ideas, admit mistakes, and ask for help. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;They Inspire Confidence:&lt;/strong&gt; By valuing input and celebrating contributions, they make their teammates feel seen and appreciated. &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; This dynamic doesn’t just improve outcomes—it strengthens relationships and creates a sense of shared purpose.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; How to Foster Collaborative Intersections  &lt;/h3&gt;

&lt;p&gt; The magic happens at the intersections where collaboration thrives. Here’s what the best people I’ve worked with do to make that happen:  &lt;/p&gt;

&lt;h3&gt; For New Leaders  &lt;/h3&gt;

&lt;ol&gt; &lt;li&gt;&lt;strong&gt;Share Context Freely&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Ask for Input&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Celebrate Wins Together&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt;

&lt;h3&gt; For Teammates  &lt;/h3&gt;

&lt;ol&gt; &lt;li&gt;&lt;strong&gt;Be Proactive in Offering Support&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Focus on Solutions&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Build Relationships Through Transparency&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt;

&lt;hr&gt;

&lt;h3&gt; What Great Collaboration Looks Like  &lt;/h3&gt;

&lt;p&gt; The best collaborators understand that leadership isn’t about having all the answers. It’s about creating an environment where everyone can thrive. They model humility, transparency, and curiosity, which in turn inspires their teammates to do the same.  &lt;/p&gt;

&lt;p&gt; Collaboration is a two-way street. When leaders and teammates bring their best selves to the table, the result is more than just successful projects—it’s a culture of trust and mutual growth.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; Closing Thoughts  &lt;/h3&gt;

&lt;p&gt; If you’re stepping into a new role, remember that your title isn’t the end of the journey—it’s the beginning. And if you’re working with someone in that position, focus on creating collaborative intersections where both sides can learn and grow.  &lt;/p&gt;

&lt;p&gt; The best people I’ve worked with know this: Together, we’re not just chasing tails—we’re building something better.  &lt;/p&gt;</description>
        <pubDate>Tue, 14 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/14/the-dog-who-caught-their-tail-the-best-collaborators-i-ve-worked-with.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/14/the-dog-who-caught-their-tail-the-best-collaborators-i-ve-worked-with.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>Stand Up and Fight: Running the Gauntlet of Change</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-12-stand-up-and-fight-running-the-gauntlet-of-change.jpg&quot; alt=&quot;Stand Up and Fight: Running the Gauntlet of Change&quot;&gt;&lt;/figure&gt;

&lt;p&gt; Change, whether in ourselves or the systems we inhabit, is rarely easy. It’s a battle—a gauntlet—of meetings, justifications, setbacks, and uncertainty. For anyone who’s fought to make a project, a vision, or even a career change a reality, the battlefield can feel endless and isolating. But it’s not insurmountable.  &lt;/p&gt;

&lt;div&gt;&lt;/div&gt;

&lt;p&gt; Dropkick Murphys’ &lt;em&gt;“The Gauntlet”&lt;/em&gt; captures the essence of that struggle. Its lyrics, steeped in resilience and determination, provide a framework for how to approach the battlefield of change and emerge stronger, even when the odds feel stacked against you.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “When the walls are closing in…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“I was weighing in heavy but still feeling alright…”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; I’ve stood at the edge of uncertainty, from my blue-collar roots to transitioning into a career in technology. Changing my life wasn’t a sure thing—there was no guarantee I’d succeed. The walls often felt like they were closing in, whether it was self-doubt or the resistance I encountered in systems that didn’t want to change.  &lt;/p&gt;

&lt;p&gt; The key was recognizing that the weight of those challenges didn’t define me. I had to remind myself: feeling the weight is part of the process. You’re not failing because it’s hard—you’re growing because you keep going despite it.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “Do you think we’re gonna make it? / I don’t know unless we try…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“You could sit here scared to move or we could take them by surprise.”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; This lyric speaks directly to the core of action. There’s a moment in every battle—whether it’s for a professional goal, a personal vision, or systemic change—where you face a choice: sit back, or step forward.  &lt;/p&gt;

&lt;p&gt; For me, stepping forward meant planting seeds long before anyone could see their value. It meant justifying solutions in meeting after meeting, facing skepticism, and holding onto the belief that what I was doing &lt;em&gt;mattered&lt;/em&gt;, even when the results weren’t immediate. The lesson? You won’t know if you can make it until you try. And trying means taking the first step, even when success feels uncertain.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “They’re gonna prey upon your weakness…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“No man’s soul is ever spared.”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; In every gauntlet, your weaknesses will be tested. I learned this early—both in labor-intensive jobs and in white-collar environments. People will question your vision, your ability, and even your motives. Systems will resist change, and you’ll be forced to confront your own fears and insecurities.  &lt;/p&gt;

&lt;p&gt; The only way to survive is to prepare. Know your vulnerabilities and build resilience. When I entered tech, I didn’t have all the answers, but I was relentless in learning, adapting, and improving. That’s how you protect your soul: by refusing to let the doubts—whether internal or external—define you.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “You’ve got to stand up, yeah, and fight them…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“Show them what it’s all about.”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; This is the anthem of every meeting where I’ve had to fight for solutions that weren’t immediately obvious to others. The project no one believed in. The processes that felt too ambitious. The long, uphill battle of transforming legacy systems that others had given up on. Each of these moments was a fight—not against people, but against inertia, apathy, and fear of change.  &lt;/p&gt;

&lt;p&gt; Standing up means having clarity of purpose and the courage to see it through. It’s not about aggression—it’s about conviction. When I’ve stood up in meetings, it’s been with a mindset of collaboration, even when I’ve had to fight for my vision. Every fight was a step forward.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “Stand up and fight! / And I’ll stand up with you…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“We shall succeed.”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; The journey is never a solo endeavor. I’ve leaned on mentors, partners, and colleagues who believed in me when I struggled to believe in myself. And I’ve tried to be that support for others—encouraging them to stand up and fight for their own visions.  &lt;/p&gt;

&lt;p&gt; This lyric reminds us that we’re not alone. Whether you’re leading a team or finding your way in a new role, solidarity matters. When you stand up for what’s right, you inspire others to do the same. Together, you can achieve more than you ever could alone.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; “They won’t get me, they won’t get me…”  &lt;/h3&gt;

&lt;blockquote&gt; &lt;em&gt;“I would rather fight and die.”&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; There were times when the resistance felt overwhelming—when my ideas were dismissed or my confidence was shaken. But this lyric became my mantra. It’s a reminder that standing your ground, even when it’s hard, is better than compromising your values or vision.  &lt;/p&gt;

&lt;p&gt; Not every battle will be won, and not every seed will grow. But the act of fighting for what matters—to you, to your team, to your organization—is its own reward. It’s how you grow, learn, and ultimately succeed.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; A Call to Action: Running Your Gauntlet  &lt;/h3&gt;

&lt;p&gt; To anyone facing their own gauntlet—whether it’s changing your career, transforming a system, or realizing a personal vision—this is your moment to stand up and fight. Here’s what I’ve learned:   &lt;/p&gt;

&lt;ol&gt; &lt;li&gt; &lt;strong&gt;Prepare for the unexpected.&lt;/strong&gt; The path won’t be what you think, but that’s part of the process.  &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Focus on what you can control.&lt;/strong&gt; Plant the seeds, even when others can’t see their value yet.  &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Lean on others.&lt;/strong&gt; You don’t have to fight alone. Build a network of people who will stand with you.  &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Keep moving forward.&lt;/strong&gt; Progress is slow, but every step matters. &lt;/li&gt; &lt;/ol&gt;

&lt;p&gt; The gauntlet isn’t just a struggle—it’s a transformation. It’s where you find out who you are and what you’re capable of. And when you emerge on the other side, you’ll know: the fight was worth it.  &lt;/p&gt;

&lt;p&gt; So, what’s your gauntlet? Will you stand up and fight?  &lt;/p&gt;</description>
        <pubDate>Sun, 12 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/12/stand-up-and-fight-running-the-gauntlet-of-change.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/12/stand-up-and-fight-running-the-gauntlet-of-change.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>From Yossarian to Orr: Moving From Seeing the Problem to Solving It</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-10-from-yossarian-to-orr-moving-from-seeing-the-problem-to-solving-it.jpg&quot; alt=&quot;From Yossarian to Orr: Moving From Seeing the Problem to Solving It&quot;&gt;&lt;/figure&gt;

&lt;blockquote&gt; &lt;em&gt;There was only one catch and that was Catch-22, which specified that a concern for one’s safety in the face of dangers that were real and immediate was the process of a rational mind. Orr was crazy and could be grounded. All he had to do was ask; and as soon as he did, he would no longer be crazy and would have to fly more missions. Orr would be crazy to fly more missions and sane if he didn’t, but if he was sane he had to fly them. If he flew them he was crazy and didn’t have to; but if he didn’t want to he was sane and had to. Yossarian was moved very deeply by the absolute simplicity of this clause of Catch-22 and let out a respectful whistle. “That’s some catch, that Catch-22,” he observed. “It’s the best there is,” Doc Daneeka agreed.&lt;/em&gt;  &lt;/blockquote&gt;

&lt;p&gt; For much of my life, I’ve felt like Yossarian from &lt;em&gt;Catch-22&lt;/em&gt;. Trapped in systems that felt absurd, unyielding, and indifferent, I could see the problems clearly—how the rules worked against me and others, how progress was stifled by inefficiency and fear. But like Yossarian, I felt helpless to do anything about it. I raged, I resisted, and I tried to fight the system head-on. But the system didn’t budge.  &lt;/p&gt;

&lt;p&gt; It wasn’t until I started thinking more like Orr, Yossarian’s quietly brilliant counterpart, that I began to make real progress. Orr didn’t just see the problem—he acted. While others raged against the machine, Orr spent his time preparing. He crash-landed planes to perfect his survival tactics. He didn’t waste energy fighting battles he couldn’t win. He studied the system, found its cracks, and created a way out.  &lt;/p&gt;

&lt;p&gt; That shift—from seeing the problem to solving it—has been transformational for me.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Lesson: Seeing Isn’t Enough  &lt;/h3&gt;

&lt;p&gt; Yossarian and Orr both understood the absurdity of the system, but their responses couldn’t have been more different. Yossarian fought against it, growing increasingly frustrated and hopeless. Orr, on the other hand, accepted the system’s absurdity but refused to let it define him. He focused on what he could control, planned meticulously, and eventually outmaneuvered the system entirely.  &lt;/p&gt;

&lt;p&gt; For a long time, I was stuck in Yossarian’s mindset. I saw the flaws, the inefficiencies, the roadblocks, and I let my frustration and anger take the lead. I thought if I pushed harder, if I fought more, I could break through. But all I did was burn myself out. The system didn’t change—but I had to.  &lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt; The Shift to Orr: What I’ve Learned  &lt;/h3&gt;

&lt;p&gt; Here’s what moving from Yossarian to Orr has taught me:  &lt;/p&gt;

&lt;ol&gt; &lt;li&gt;&lt;strong&gt;Calm Is a Superpower&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Focus on What You Can Control&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Learn the Rules to Rewrite Them&lt;/strong&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Prepare for the Long Game&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt;

&lt;hr&gt;

&lt;h3&gt; Moving Forward With Purpose  &lt;/h3&gt;

&lt;p&gt; Many of us feel like Yossarian at some point—seeing the problems in our systems but feeling powerless to address them. It’s an overwhelming place to be. But we don’t have to stay there. By shifting our mindset and actions, we can move from frustration to strategy, from reacting to creating.  &lt;/p&gt;

&lt;p&gt; The journey from Yossarian to Orr isn’t easy. It requires patience, clarity, and focus. But the rewards are worth it. When we stop fighting against the system and start thinking our way through it, we create something far more powerful than resistance: real progress.  &lt;/p&gt;

&lt;p&gt; So, if you’re feeling stuck or overwhelmed, ask yourself: What would Orr do? How can you prepare, adapt, and quietly build your path forward? The answer might surprise you—and it might just set you free.  &lt;/p&gt;

&lt;hr&gt;

&lt;ul&gt; &lt;li&gt; Image sourced from Wikimedia Commons: &lt;a href=&quot;https://commons.wikimedia.org/wiki/File:Catch22-1970_opening.jpg&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://commons.wikimedia.org/wiki/File:Catch22-1970_opening.jpg&lt;/a&gt; &lt;/li&gt; &lt;li&gt; Quote by &lt;em&gt;Joseph Heller&lt;/em&gt; author &lt;em&gt;Catch-22&lt;/em&gt; sourced from &lt;a href=&quot;https://www.goodreads.com/quotes/33830-there-was-only-one-catch-and-that-was-catch-22-which&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Goodreads&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;</description>
        <pubDate>Fri, 10 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/10/from-yossarian-to-orr-moving-from-seeing-the-problem-to-solving-it.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/10/from-yossarian-to-orr-moving-from-seeing-the-problem-to-solving-it.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>Practice vs. Repetition: The Key to Real Growth</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2025-01-04-practice-vs-repetition-the-key-to-real-growth.jpg&quot; alt=&quot;Practice vs. Repetition: The Key to Real Growth&quot;&gt;&lt;/figure&gt;

&lt;p&gt; We’ve all heard the phrase, “Practice makes perfect.” But does it? Not really.  &lt;/p&gt;

&lt;p&gt; Practice doesn’t make perfect. It makes you &lt;em&gt;better&lt;/em&gt;. But only if you’re doing it right.  &lt;/p&gt;

&lt;p&gt; Here’s the thing: &lt;strong&gt;practice&lt;/strong&gt; and &lt;strong&gt;repetition&lt;/strong&gt; are not the same. Repetition—mindlessly doing the same thing over and over—will only make you better at doing that one specific thing, flaws and all. Practice, on the other hand, is intentional. It involves analyzing, experimenting, reflecting, and improving as you go.  &lt;/p&gt;

&lt;p&gt; &lt;strong&gt;Think about it this way:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; Repetition is attempting the same skateboard trick in place, never adjusting your approach. &lt;/li&gt; &lt;li&gt; Practice is trying that trick on a winding skate park path—learning, falling, and progressing toward landing it. &lt;/li&gt; &lt;/ul&gt;

&lt;h3&gt; Why Practice Matters  &lt;/h3&gt;

&lt;p&gt; Practice is like paying into the “mortgage” of your skills. Every session is an investment in future returns. Sometimes the return is huge, and you see massive improvement. Other times, it’s smaller—a fractional gain. But here’s the kicker: you &lt;em&gt;always&lt;/em&gt; get something. Even if the return is just the knowledge that you weren’t meant to pursue that skill long-term, you’ve learned something valuable.  &lt;/p&gt;

&lt;p&gt; When I was reteaching myself skateboarding in my 40s, I had to accept the limits in my practice. I had to adjust my expectations so I could work through significant challenges and fears. Before each trick, I would repeat to myself, “All that matters is the rideaway.” Pushing through the fear of falling or failing, I focused on following through—on finishing the trick, no matter the outcome. What I was really practicing wasn’t just the trick—it was &lt;strong&gt;commitment&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt; I even wrote it on my griptape as a psychological reminder every time I looked down at my board before a run at the curb, an obstacle, or dropping in on a ramp. All that mattered was the rideaway—and that required commitment.  &lt;/p&gt;

&lt;h3&gt; Embrace Imperfection  &lt;/h3&gt;

&lt;p&gt; We live in a world obsessed with perfection. But here’s the truth: the perfect product, system, or performance doesn’t exist. What does exist is the willingness to create something, no matter how “crappy” it seems at first. That’s where growth happens.  &lt;/p&gt;

&lt;p&gt; Some of the most successful companies and systems in the world started as messy, flawed experiments. I’ve seen it firsthand: imperfect products being used by real customers, while the “perfect” systems remain stuck in development.  &lt;/p&gt;

&lt;p&gt; The lesson? &lt;em&gt;Execution beats perfection.&lt;/em&gt; The willingness to act—to create, learn, and refine—is what drives real progress.  &lt;/p&gt;

&lt;h3&gt; What About You?  &lt;/h3&gt;

&lt;ul&gt; &lt;li&gt; Are you practicing with intention or just repeating? &lt;/li&gt; &lt;li&gt; How do you balance imperfection with progress? &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; I’d love to hear your thoughts. Share your experiences in the comments—let’s start a conversation about how we can grow smarter, not just harder.  &lt;/p&gt;</description>
        <pubDate>Sat, 04 Jan 2025 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2025/01/04/practice-vs-repetition-the-key-to-real-growth.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2025/01/04/practice-vs-repetition-the-key-to-real-growth.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>What Seasoned Developers Forget About Starting Out</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2024-12-28-what-seasoned-developers-forget-about-starting-out.jpg&quot; alt=&quot;What Seasoned Developers Forget About Starting Out&quot;&gt;&lt;/figure&gt;

&lt;p&gt; Sitting with a half-dozen senior technologists at my local user group, we were joined by half as many junior developers eager to learn. After all, they came to a software craftsmanship meetup—they were ready to soak up knowledge.  &lt;/p&gt;

&lt;p&gt; The seasoned developers among us started chatting about our work challenges. We felt so smart, sharing our hard-earned wisdom. Then, one of the junior members asked a simple yet profound question:   &lt;/p&gt;

&lt;blockquote&gt; &lt;strong&gt;&quot;Do you have any career advice?&quot;&lt;/strong&gt;  &lt;/blockquote&gt;

&lt;p&gt; Naturally, we responded with advice tailored to the problems we’re dealing with today—problems shaped by 20+ years in the industry. I can’t recall exactly what we said, but looking back, it didn’t matter. It was meaningless to someone just starting out.  &lt;/p&gt;

&lt;p&gt; That realization hit me. Our advice was for people with decades of experience, not for someone navigating today’s entry-level job market—a landscape vastly different from the one we entered.  &lt;/p&gt;

&lt;p&gt; So, I paused and reframed the conversation.   &lt;/p&gt;

&lt;p&gt; I asked the junior developer, &lt;strong&gt;&quot;What’s your language?&quot;&lt;/strong&gt; Whatever they said, I told them it was perfect. Because it &lt;em&gt;is&lt;/em&gt;—it’s &lt;em&gt;their&lt;/em&gt; language. It’s the foundation of their journey, and there’s no point arguing otherwise.  &lt;/p&gt;

&lt;p&gt; I shared what I hoped was more practical advice:   &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; Focus on your toolkit. Master your language, learn to write tests, and understand your build scripts.  &lt;/li&gt; &lt;li&gt; Spend time optimizing your environment. Learn your IDE, terminal, and editor.  &lt;/li&gt; &lt;li&gt; Find resources that teach fundamentals in a fun and engaging way. I love Dave Farley’s work, but I also recommend checking out someone like The Primeagen on YouTube. Keep an open mind!  &lt;/li&gt; &lt;li&gt; Explore tools like ChatGPT—but learn their limits as well as their strengths.  &lt;/li&gt; &lt;li&gt; Attend user groups, webinars, and meetups. Surround yourself with people who share your curiosity.  &lt;/li&gt; &lt;li&gt; Be patient with Agile, TDD, or any process your company uses. Pay attention to the pain points—they’re often signaling something deeper.  &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; For those of us further along in our careers, it’s tempting to offer advice that mirrors our own paths or solves the challenges we face today. But we must remember: there’s a 20-year gap between their &lt;em&gt;now&lt;/em&gt; and our &lt;em&gt;today&lt;/em&gt;.   &lt;/p&gt;

&lt;p&gt; People need space to learn how to learn. They need room to discover what we often take for granted. Let’s not forget what it felt like to &lt;em&gt;not know&lt;/em&gt; yet.   &lt;/p&gt;</description>
        <pubDate>Sat, 28 Dec 2024 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2024/12/28/what-seasoned-developers-forget-about-starting-out.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2024/12/28/what-seasoned-developers-forget-about-starting-out.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>Mentorship Starts With a Conversation</title>
        <description>&lt;figure&gt;&lt;img src=&quot;/assets/images/writing/linkedin/2024-12-28-mentorship-starts-with-a-conversation.jpg&quot; alt=&quot;Mentorship Starts With a Conversation&quot;&gt;&lt;/figure&gt;

&lt;p&gt; If you&apos;re a senior developer working with colleagues just a few years junior to you, you already have everything you need to be a mentor. It doesn’t take years of preparation or a formal program to begin—it starts with curiosity and conversation.   &lt;/p&gt;

&lt;p&gt; Ask about their setup:   &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; &lt;em&gt;&quot;Which fonts do you use in your editor?&quot;&lt;/em&gt;  &lt;/li&gt; &lt;li&gt; &lt;em&gt;&quot;Oh, you use X IDE? How do you like that workflow?&quot;&lt;/em&gt;  &lt;/li&gt; &lt;li&gt; &lt;em&gt;&quot;I noticed you use X technique for this task. That’s cool—here’s how I approach it with Y. I like what you did with X—maybe I can integrate that into my process.&quot;&lt;/em&gt;  &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; These small exchanges are the first steps towards mentorship. When you open the door by being curious and genuinely interested in how someone works, you show respect for their ideas. You also set the stage for mutual learning—mentorship isn’t a one-way street.   &lt;/p&gt;

&lt;p&gt; When you engage this way, you build confidence:   &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; You’re implicitly saying, &lt;em&gt;“What you do matters.”&lt;/em&gt;  &lt;/li&gt; &lt;li&gt; Recognizing their strengths helps junior developers feel valued.  &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; And mentorship is a learning opportunity for you, too. Junior developers often bring fresh ideas or approaches you might not have considered. By being curious, you might discover something new or see a challenge from a different perspective.   &lt;/p&gt;

&lt;p&gt; Mentorship also makes collaboration easier. When people feel heard and supported, they’re more likely to share ideas and ask for help. A team where everyone feels valued—regardless of experience—works more cohesively.   &lt;/p&gt;

&lt;p&gt; Start small:   &lt;/p&gt;

&lt;ul&gt; &lt;li&gt; Invite someone to pair program.  &lt;/li&gt; &lt;li&gt; Ask for their opinion during a code review and explain why you value it.  &lt;/li&gt; &lt;li&gt; Share a small trick you’ve picked up, and ask if they have one to share.  &lt;/li&gt; &lt;/ul&gt;

&lt;p&gt; These conversations build trust and open the door for deeper collaboration.   &lt;/p&gt;

&lt;p&gt; Mentorship doesn’t have to be formal or intimidating. It begins with respect, curiosity, and a willingness to learn from each other.   &lt;/p&gt;

&lt;p&gt; So go ahead: ask about their fonts. Ask about their techniques. Watch how these simple conversations transform your relationships, your team, and even your own perspective on growth.   &lt;/p&gt;</description>
        <pubDate>Sat, 28 Dec 2024 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2024/12/28/mentorship-starts-with-a-conversation.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2024/12/28/mentorship-starts-with-a-conversation.html</guid>
        
        <category>linkedin</category>
        
        <category>republished</category>
        
      </item>
    
      <item>
        <title>Leverage the &quot;J&quot; in JRuby for Powerful Concurrency</title>
        <description>&lt;p&gt;I was working on a project that required some heavy-weight processing of links
to determine if they were valid based on a variety of criteria. Since the
standard Ruby interpreter was running each process sequentially the naive
approach was taking a prohibitively long time. Fortunately this was a simple
pure Ruby problem and each record was processed independently of each other this
was a good opportunity to use JRuby and it’s Java interoperability to get some
real concurrency power.&lt;/p&gt;

&lt;p&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ruby-concurrent&lt;/code&gt; library and JRuby Interop I first load in the Java
Futures libraries.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Callable&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Executors&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;FutureTask&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LinkedBlockingQueue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ThreadPoolExecutor&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;java_import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TimeUnit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the goal is to squeeze as many executions as possible I set the pool size
to saturate all available cores.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;POOL_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getRuntime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;availableProcessors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The application reads in a CSV and writes each row into a threadsafe array for
later processing. Since the input itself wasn’t the bottleneck sequentially
reading in the file had little impact on the execution time.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_to_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@queue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ThreadSafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;CSV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_to_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;r&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;App.work&lt;/code&gt; sets up the futures creation and execution. I looped over the queue
of rows and create a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Worker&lt;/code&gt; (defined below) and hand that off to the Java
Future in preparation for execution. Again, the list of tasks in the queue
wasn’t the bottle next so enumerating over the queue was not a significant
impact on the execution performance.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;work&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ThreadSafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;executor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;POOL_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;POOL_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TimeUnit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SECONDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LinkedBlockingQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pop&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;shift&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FutureTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;executor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As each future completes it’s work the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tasks&lt;/code&gt; array enumerates the results of
the worker execution. In this case I’m just writing the output to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;STDOUT&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:passed&lt;/span&gt;
        &lt;span class=&quot;vg&quot;&gt;$stdout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;vg&quot;&gt;$stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;executor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;shutdown&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Worker&lt;/code&gt; implements the actual reason for the script. We include Java’s
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Callable&lt;/code&gt; module so we can work with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FutureTask&lt;/code&gt; defined above.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Worker&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;util&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;concurrent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Callable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is less important but represents some of the work being done. It was a
rough experiment and the data was a mess. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scrub_input&lt;/code&gt; was kind of a work
in progress.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;nb&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:input&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:data&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scrub_input&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@input&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^(%20|%3c|%22)+/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^(\\)+/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/(%20|%3c|%22)+$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^[-.]+/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^#+/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the rules were being implemented in a plugin style I had a little fun with
the naming. I’ll leave the references up to you.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scrub_input&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;inspector&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;BeetInspector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TldBeet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DomainBeet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LocalpartBeet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SuppressionListBeet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;KeywordBeet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Schrute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Beets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;TelnetBeet&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here I take the result of the input inspector and format it so it can be
returned and handled by the executor.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;      &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;passed?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:passed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:failed&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;status: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;email: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;input: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;data: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;reason: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:evaluation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reasons&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the code was implemented in a single script file the execution is defined
at the bottom.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;file_to_process&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Usage: process &amp;lt;file_to_process.csv&amp;gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_to_process&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_to_process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The original &lt;a href=&quot;https://gist.github.com/just3ws/e0c6b47f22a32ad16f1a&quot;&gt;gist&lt;/a&gt; is up
on GitHub. In the end using this technique reduced a multiple hour process into
a few minutes. There was some tweaking for handling particularly slow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Beets&lt;/code&gt;
but those were separate issues entirely.&lt;/p&gt;
</description>
        <pubDate>Mon, 27 Apr 2015 00:00:00 -0500</pubDate>
        <link>https://www.just3ws.com/2015/04/27/leverage-the-j-in-jruby-for-powerful-concurrency.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2015/04/27/leverage-the-j-in-jruby-for-powerful-concurrency.html</guid>
        
        <category>Ruby</category>
        
        <category>JRuby</category>
        
        <category>Java</category>
        
        <category>Concurrency</category>
        
        <category>JVM</category>
        
      </item>
    
      <item>
        <title>Using Postgres RegEx Expressions to Find Very Specific Matches</title>
        <description>&lt;p&gt;Coderwall has been having issues with certain avatars generating 403 errors in
the browser console. You probably wouldn’t notice unless you had your dev tools
open while you were browsing but there were a little over 25% of our Twitter
avatars that weren’t rendering properly due to trying to connect via HTTP
instead of HTTPS. (&lt;em&gt;And other changes to how Twitter resolves it’s profile
images but that’s a bigger issue.&lt;/em&gt;) Fortunately with the power of Ruby and
Postgres RegEx selectors it’s relatively trivial to find and transform the HTTP
urls to use HTTPS.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;twitter_token is not null AND thumbnail_url ~ &apos;^https:&apos; AND thumbnail_url ~ &apos;twimg&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;com&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find_each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;batch_size: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;profile_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Update &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; because &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;profile_url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; appears to be HTTP.&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;scheme&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;https&apos;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;update_attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:thumbnail_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; ==&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;profile_url&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;InvalidURIError&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;User&lt;/code&gt; model has a field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url&lt;/code&gt; which holds the URL for users who
log into Coderwall via OAuth. Since the issue was currently a problem
predominantly for Twitter logins, and LinkedIn doesn’t allow for fetching the
thumbnails via HTTPS, I first limited the query to known Twitter login users.&lt;/p&gt;

&lt;p&gt;Next I want to filter by users who have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url&lt;/code&gt;’s that are not already
using HTTPS. That number was near-zero after some poking I did to verify the
issue, but better to be safe than sorry and it also helps with re-running the
script, no sense in selecting a record that’s already been updated. I used the
Postgres RegEx matcher &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url ~ &apos;^https:&apos;&lt;/code&gt; but could very well have used
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url ilike &apos;https:%&apos;&lt;/code&gt; which can still utilize some indexes if
available. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilike&lt;/code&gt; vs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;like&lt;/code&gt; is also preferable in this case because it is
case-insensitive&lt;/p&gt;

&lt;p&gt;The last part of the query &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url ~ &apos;twimg\.com&apos;&lt;/code&gt; could have also been
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url ilike &apos;%twimg.com%&apos;&lt;/code&gt; but was used because I was refactoring from
matchers that were inside the block as I was testing this little bit of
functionality.&lt;/p&gt;

&lt;p&gt;Then I used the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find_each(batch_size: 500)&lt;/code&gt; to fetch the records in batches of
500 to avoid excessive queries. Given this batch size I did about 56+ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;select&lt;/code&gt;s
instead of 28,000+.&lt;/p&gt;

&lt;p&gt;We can fetch Avatars from a few different places so we abstract the url via the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;profile_url&lt;/code&gt; method. I could have just fetched from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thumbnail_url&lt;/code&gt; but it
didn’t make any difference in this case. I load the url into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;URI.parse&lt;/code&gt; so I
can manipulate the url without string manipulation. I convert the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; on
the URI instance and then update the attribute on the model. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puts&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ap&lt;/code&gt;
(awesome_print) statements are just there to help me as I watch the process run.&lt;/p&gt;

&lt;p&gt;While the query could have further been simplified via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ilike&lt;/code&gt; wildcard
statements the Postgres RegEx expressions are very useful for matching data
inside a Postgres instance and let you have extremely fine grained control over
the your results without having to pull more than you absolutely must from the
database. They come at a cost of being rather non-index friendly but they are a
useful tool to have at your disposal when you need it.&lt;/p&gt;
</description>
        <pubDate>Wed, 25 Feb 2015 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2015/02/25/using-postgres-regex-expressions-to-find-very-specific-matches.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2015/02/25/using-postgres-regex-expressions-to-find-very-specific-matches.html</guid>
        
        <category>PostgreSQL</category>
        
        <category>RegEx</category>
        
        <category>Ruby on Rails</category>
        
        <category>SQL</category>
        
      </item>
    
      <item>
        <title>Improve Case-Insensitive Queries in PostgreSQL Using Smarter Indexes</title>
        <description>&lt;p&gt;One of the unique features of Postgres is it’s powerful index engine.
Using Postgres you can get much more fine grained control over how your
data is indexed. For example indexes on expressions which allow you to
create indexes on fields that have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UPPER&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOWER&lt;/code&gt; functions applied
to them.&lt;/p&gt;

&lt;p&gt;Typically a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VARCHAR&lt;/code&gt; field is case-sensitive in Postgres. Meaning that
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fieldname = &apos;FOO&apos;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fieldname = &apos;foo&apos;&lt;/code&gt; won’t match when the actual
value is “FOO”. A common technique is to normalize the field value like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lower(fieldname) = lower(&apos;FOO&apos;)&lt;/code&gt; to coerce the fields to match using
their lower-case form. The problem is that this will ignore indexes and
cause Postgres to use a Sequential Scan to find the match evaluating
each row looking for a match. This is expensive and non-ideal for large
and frequently queried tables.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;QUERY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLAN&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-----------------------------------------------------------&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;Seq&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13327&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;558&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Compare that to the query with no expression and a simple index on the username
field.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                                     &lt;span class=&quot;n&quot;&gt;QUERY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLAN&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-------------------------------------------------------------------------------------&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index_users_on_username&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;07&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s a significant cost to pay when querying against expressions. But
all is not lost. Postgres will let you build &lt;a href=&quot;https://www.postgresql.org/backlog/docs/current/static/indexes-expressional.html&quot;&gt;indexes against
expressions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this case we’ll apply a index that will take the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lower()&lt;/code&gt; expression
into account.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ix_users_username_lower&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;varchar_pattern_ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now when we query for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lower(usernames)&lt;/code&gt; we’ll be able to take advantage
of the index to avoid full table scanning.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                                       &lt;span class=&quot;n&quot;&gt;QUERY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLAN&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;----------------------------------------------------------------------------------------&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Heap&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;988&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;43&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;558&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;Recheck&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;Bitmap&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scan&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ix_users_username_lower&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;558&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;just3ws&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s much better than the Sequential Scan now although still a little
bit slower than just querying against the simple index.&lt;/p&gt;

&lt;p&gt;The Bitmap Heap Scan is useful when there is a lot of variety in the
data and Postgres is able to intelligently segregate the data. Basically
the data is chunked into smaller sets that Postgres can filter though
and more intelligently decide which sets to scan and which to skip.
Where the Sequential Scan will touch every single row in the table.&lt;/p&gt;

&lt;p&gt;Read more about the Postgres &lt;a href=&quot;https://www.postgresql.org/backlog/docs/current/static/indexes-expressional.html&quot;&gt;Index on
Expressions&lt;/a&gt;
in the official documentation and this explanation by the author of the
&lt;a href=&quot;https://www.postgresql.org/message-id/12553.1135634231@sss.pgh.pa.us&quot;&gt;Postgres Bitmap Heap Scan
algorithm&lt;/a&gt;
Tom Lane.&lt;/p&gt;

&lt;p&gt;For a full explanation of what the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cost&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rows&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;width&lt;/code&gt; values
mean please check out &lt;a href=&quot;https://www.postgresql.org/backlog/docs/current/static/using-explain.html&quot;&gt;Using
Explain&lt;/a&gt;
from the Postgres documentation.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;varchar_pattern_ops&lt;/code&gt; is explained in Postgres
&lt;a href=&quot;https://www.postgresql.org/backlog/docs/current/static/indexes-opclass.html&quot;&gt;Index&lt;/a&gt;
documentation.&lt;/p&gt;
</description>
        <pubDate>Wed, 25 Feb 2015 00:00:00 -0600</pubDate>
        <link>https://www.just3ws.com/2015/02/25/improve-case-insensitive-queries-in-postgres-using-smarter-indexes.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2015/02/25/improve-case-insensitive-queries-in-postgres-using-smarter-indexes.html</guid>
        
        <category>PostgreSQL</category>
        
        <category>Indexes</category>
        
        <category>SQL</category>
        
        <category>Performance</category>
        
      </item>
    
      <item>
        <title>360 Learning at User Groups</title>
        <description>&lt;h2 id=&quot;retrospective&quot;&gt;Retrospective&lt;/h2&gt;

&lt;p&gt;This article reflects on the idea that learning at user groups is multi-directional: the speaker, the audience, and the organizer all learn in different ways at the same time. The key insight is that facilitation is an active craft, and that “360 learning” emerges when the group creates space for questions, pacing, and shared problem-solving.&lt;/p&gt;

&lt;h2 id=&quot;original-text&quot;&gt;Original text&lt;/h2&gt;

&lt;h4 id=&quot;first-a-small-plug-for-my-user-group-community&quot;&gt;First a small plug for my user-group community.&lt;/h4&gt;

&lt;p&gt;[Software Craftsmanship North America](http://mchenry.softwarecraftsmanship.org) (SCMC) is a group that meets once a month at [Follett Software Company](http://www.follettsoftware.com/) in the far-northwestern suburbs of Chicago. We’re a diverse group of individuals with members in their teens all the way up to the great grandparents of software development. It’s a lot of fun and we always learn something at each meeting.&lt;/p&gt;

&lt;h3 id=&quot;theres-more-to-learn-than-just-the-topic-at-user-groups&quot;&gt;There’s more to learn than just the topic at User-groups.&lt;/h3&gt;

&lt;p&gt;I think that user-group meeting topics are just the tip of the learning possibilities at user-group meetings but you have to take a step back to get the full picture.&lt;/p&gt;

&lt;p&gt;Let’s paint the scene. Last night [Surya Gaddipati](http://twitter.com/suryagaddipati) was presenting on his work in building [LINQR](https://github.com/suryagaddipati/linqr), a [LINQ DSL in Ruby](http://www.meetup.com/Software-Craftsmanship-McHenry-County/events/79576612/). He was presenting to 11 software professionals who were mostly versed in Java and C++ programming.&lt;/p&gt;

&lt;p&gt;Let’s look at the possibilities for learning within the group…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The speaker who’s creating a very cool set of utilities for Ruby was presenting on a very dense set of topics for the first time.&lt;/li&gt;
  &lt;li&gt;Many people in the audience were not .NET developers or Ruby developers so they were simultaneously trying to absorb the DSL concepts but also enough Ruby and .NET concepts for it to make sense.&lt;/li&gt;
  &lt;li&gt;As the meeting facilitator I learned a lot about the dynamic of the group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This multi-faceted learning is what I think is very unique about user-groups. I’ll write a comparison of tech conference learning opportunities in another post.&lt;/p&gt;

&lt;h3 id=&quot;what-did-the-speaker-learn&quot;&gt;What did the speaker learn?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Don’t try to pack too much information into one meeting.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember over the months and years you’ve spent learning or building whatever your presenting on that there’s almost no way to summarize that down into a one or two hour session. You need to choose to go deep or wide. If you go deep then you’ll need to pick one facet and just focus on that bringing in only enough to support that topic. If you go wide you’ll likely be discussing things in broad stokes, only giving enough detail for context.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Lean on your organizer.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any trouble with technical aspects or with how to engage your audience, then speak to the organizer. They’re there to make sure everyone has a good time and gets as much value as possible. If you’re stuck then mention it, your organizer probably knows the technical difficulties already and can rescue you quickly. If your audience is a sea of blank faces sometimes engaging your organizer directly can give them a clue that you need some more interaction and they can help with engaging the group on your behalf.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Lean on your audience.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time the audience is very technical and has something to offer besides attention. If you do get stuck it’s also okay to say, “Ugh. I can’t remember how to set the color scheme on my Vim, does anyone know how to change that?” It’s hard to remember these kinds of things when you’re under pressure in front of a live audience. By breaking the “fourth wall” and asking for help you’ve let the audience in on you a little and they’ll often be more patient, understanding and engaged because you’ve let some of your humanity show.&lt;/p&gt;

&lt;h3 id=&quot;what-did-the-audience-learn&quot;&gt;What did the audience learn?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Know when the firehouse is open too wide.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes when there’s just too much information to be synthesized all at once audiences will typically kind of shutdown and become less likely to ask questions. This is your chance as an organizer to interject with a question or try to work with the speaker and audience to figure out what’s the right level of content for people to get value. If things are too high-level for the audience they’ll leave more confused but too low-level and they’ll get bored and just leave. I like to sometimes start with a question to the speaker and then turn it back around to the group to encourage feedback and interaction.&lt;/p&gt;

&lt;h3 id=&quot;what-did-i-as-the-facilitator-learn&quot;&gt;What did I as the facilitator learn?&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;You know your group better than your speaker does.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you’re getting a presenter who’s a regular member of the group they’re probably not experienced in reading the body language of the people in the group yet. As the group leader you’ve had a lot more chances to see how your people react in different situations.&lt;/p&gt;

&lt;p&gt;If you the group getting uncomfortable with the pace of a presentation then maybe take a moment to ask a question or make a comment that we might need to slow down a bit or speed up the presentation a little. I’ve interjected with “That’s neat. Can you show us an example?” or be the first to plead ignorance “I’m sorry I didn’t understand what you meant by ‘Foo bar baz’?”. These can give clues to the presenter and also break the ice for the other people in the audience to ask their own questions.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Save a struggling presenter.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if we’ve practiced our talks sometimes things go wrong. If the presenter seems to be stuck with a technical problem or just seems to be getting a bit nervous then you should give them a break and move the focus off them so they can recover.&lt;/p&gt;

&lt;p&gt;If they’re having trouble with the keyboard or projector during a presentation and seem to be struggling to catch up that will usually escalate whatever their anxiety levels might already be from public speaking. Take a chance to get everyone who’s staring at them to look away. Mention that there’s still food, suggest a short break or start a side-conversation. That takes the spotlight off the presenter and then you can move in to help resolve the issue, offer a few words of encouragement and then prepare to resume the presentation.&lt;/p&gt;

&lt;h3 id=&quot;bringing-it-all-around&quot;&gt;Bringing it all around.&lt;/h3&gt;

&lt;p&gt;The concept of 360 degrees of learning is that everyone has a chance to learn, the facilitator, the presenter and the audience. The learning opportunities come full circle and that’s something that is easier to do in small groups that meet somewhat frequently. This 360 degree learning is something I didn’t anticipate when I started SCMC but something I’ve learned to value and is partly why I want to support user-group communities through UGtastic. When we have such opportunities to learn I can’t help but say, “&lt;strong&gt;User-groups? Fantastic!&lt;/strong&gt;”.&lt;/p&gt;
</description>
        <pubDate>Wed, 26 Sep 2012 00:00:00 -0500</pubDate>
        <link>https://www.just3ws.com/2012/09/26/360-learning-at-user-groups.html</link>
        <guid isPermaLink="true">https://www.just3ws.com/2012/09/26/360-learning-at-user-groups.html</guid>
        
        <category>Community</category>
        
        <category>User Groups</category>
        
        <category>Learning</category>
        
        <category>Facilitating</category>
        
      </item>
    
  </channel>
</rss>
