Code, Content, and Career with Brian Hogan logo

Code, Content, and Career with Brian Hogan

Archives
Subscribe
Jan. 31, 2026, 7:13 p.m.

Issue 49 - Fluency, "A" Players, and a Lightweight Monitoring Tool

"Unpack why programming fluency matters, learn to spot an "A" player, and explore web app monitoring tool, Updo."

Code, Content, and Career with Brian Hogan Code, Content, and Career with Brian Hogan

In this issue, you'll find a few ways you can identify if someone really is an "A" player, and you'll explore a tool that lets you monitor your web applications. But first, you'll look at why understanding programming language syntax isn't enough.

Programming Language Competence Is More than Syntax

There's a common phrase I hear every so often, and it's "I don't know [some language], but I know [a different language], and they're all pretty much the same." And when I hear this, it tells me that the person might not have a lot of experience in more than one language.

It's true that every programming language turns some text you type into some instructions for the computer to run. It's all ones and zeros. But saying you know JavaScript and so Rust is "pretty much the same thing" is like saying you know English, so picking up Mandarin should be trivial as well.

Going beyond mechanics

Spoken languages have syntax, grammar, and structure, just like programming languages. But they also have dialects and cultures. You can get proficient at the language's grammar, syntax, and structure, but then when you converse with a native speaker, things don't go as smoothly as you thought. They'll be able to understand you, but they'll also immediately know that you're an outsider, because you don't know the culture, the slang, or the "way things are done." You're not fluent in the language. You haven't immersed yourself in it and invested the time to absorb anything beyond the language's mechanics.

This happens all the time in programming languages. For example, someone will learn Java, and then they'll learn another language like Ruby, and they'll bring over a lot of their Java habits with them, including their design patterns. But Ruby has its own patterns and features that make some of those Java habits unnecessary. The Java developer might use the Strategy pattern or Command pattern to pass behavior around, but Ruby has blocks and procs built into the language, and that's one approach Ruby developers use to solve problems instead of those traditional design patterns.

That same developer who picks up Go has to learn a whole new way of dealing with errors, because the concepts they're used to don't even exist there. Java and Ruby have exception handling, but Go doesn't; it relies on handling explicit error returns from function calls.

You gain fluency through immersion

Every time you learn a new programming language, you have to learn a new way of thinking in addition to absorbing new syntax. You absorb the patterns you see. When you start working in a new language, your code in the new language tends to look like the code you wrote in the language you're more familiar with. But with time and practice, you absorb the culture, and your code transforms as your understanding grows. That investment is what makes you fluent, not just productive. And that investment is what makes you effective at your job.

One of the more interesting things I've seen in my career is the work that the Temporal SDK team does. They've shipped SDKs in Go, Java, TypeScript, Python, C#, and Ruby, and each one of those SDKs looks like it "belongs" in its respective ecosystem. The TypeScript SDK uses async functions because that's how TypeScript developers expect to write code. The Ruby SDK uses classes and blocks. Each SDK reflects how that community actually works with code.

I got to watch them build two SDKs when I worked at Temporal. The SDK engineers spent countless hours learning the ins and outs of how each of those communities worked. The person who wrote the Ruby SDK hadn't written Ruby code professionally, but he did his homework, asked questions, engaged with the community, and created something that feels familiar and takes advantage of specific language features. It took an incredible amount of experience, effort, and care to make that happen. He focused on becoming fluent, not just productive. And that's the distinction people with less experience miss.

You can't swap one skill for another

Programming languages aren't interchangeable. You're unlikely to get a job doing Python development if you only have JavaScript experience. Remember, companies don't hire you to write code; they hire you to use your experience to solve problems that make them money. They need you to be fluent when you join.

This is a trap that non-technical managers and leaders fall into; they think a person fluent in one area of software development is automatically fluent in another. They might hire a developer who doesn't know the language or frameworks well and then hold that new hire to unrealistic expectations or timelines. Or they may reassign a developer who knows Python to work on a front-end project. That person spends months feeling incompetent at something they never signed up for, so they leave for another role. It's a bad time for everyone involved.

You absolutely can take your existing coding skills, adopt a new programming language, and start producing things quickly. And you should do that because it makes you a better software developer overall. But to become fluent, you must immerse yourself in the culture. You'll have to learn the idioms. And that's not trivial.

How to spot "A" players

Everybody says they want to work with "A" players. Whether that means they want to work for an "A" player, they want to work with an "A" player, or they want to hire an "A" player. And of course, we want to think of ourselves as "A" players. But what does it really mean to be one?

I've worked in both the public and private sectors, and I've met several true "A" players. They all shared the same qualities, and none of them were about domain expertise. It all comes down to how they carry themselves and how they interact with others, and it starts with owning outcomes. Here are the qualities I've observed, along with questions you can ask to see if they meet the criteria.

They hold themselves accountable and responsible for outcomes

"A" players are responsible and accountable for their decisions and their actions. When something goes wrong, it's not about how the team failed or how someone else didn't deliver it. It's about owning the decision they made and how they plan to show up next time to make sure they don't repeat the mistakes.

Ask them about a time they made a decision that went poorly, and then have them explain what happened. If they use "I "statements, that's usually a good sign. But if they start using "they "or "we, "then you may want to dig a little deeper because they're not taking full ownership. An "A" player is happy to share the spotlight when things go well, but also isn't afraid to own the outcomes when things go wrong.

They have an internal drive, even when nobody is watching.

"A" players don't need to be pushed. They identify what needs doing without being prompted or pushed. They're self-directed, but that doesn't mean they go rogue. That's because they also care about standards when nobody else is watching. They know that someone will have to follow their work or build upon it. They're going to look for buy-in and collaboration when possible.

To evaluate this, ask them what they work on when nobody is telling them what to do. They should be able to tell you, concisely, how they work. And they should be able to explain how they do it with quality, while working with others.

They show discipline even in chaos

"A" players can get things done when things are messy or unclear. They don't need perfect instructions. They prioritize, they make adjustments on the fly, and they don't panic when the plans change. They know that plans change, and they view change as an opportunity for growth.

One of my favorite questions to ask interview candidates to test for this is "What do you do when you have competing priorities?" An "A" player will be able to tell you how they think and prioritize clearly, and how they negotiate the priorities.

They have integrity.

"A" players do the right thing, even when nobody is watching, even when it can cost them. They also understand that winning isn't as important as how you win. "A" players don't burn bridges. They also know how to pick their battles. They can't fight every injustice, so they'll save their energy for things that matter to them. And when things clash with their core beliefs, they will leave, because they know that integrity is part of their reputation, and it follows them around.

Ask them, "Tell me about a time you said no to something that would have helped you in the short term," and see how they respond. An "A" player will not only talk about it, but they'll feel confident in the outcome, because they own their decisions.

They want growth

"A" players are looking to get better every day. They don't want more work to do, especially if it's more of the same work they already do well. They want more responsibility. They want to stretch. They want more trust, and they want bigger challenges, because that's how they get better. Their internal drive and desire for responsibility and accountability push them towards opportunities where they think they can contribute and get better. They also want feedback to identify what works well and what doesn't.

Ask them what they want to be better at a year from now. Their answer will tell you a lot. You'll see their drive and hunger. They'll tell you small pieces about how they plan to get there. And if they don't, you're probably not looking at an "A" player.

They don't stay if they're stalled

"A" players are looking to be the "worst player in the band." They want to surround themselves with people who are better than they are so they can be challenged and grow. As soon as they feel they've done all they can do and there's no place for them to go, they're going to move on, even if the money is good. They often won't make a big show of it because, again, they don't want to burn bridges. They'll just quietly head for the door.

They'll stop speaking up in meetings, and they'll stop volunteering for things. Their integrity will keep them showing up and doing great work. But they are moving quickly to find something that offers them the growth they need.

They won't last long reporting to "B" and "C" players.

Steve Jobs famously said, "'A' players hire 'A' players, but 'B' players hire 'C' players, and 'C' players hire 'D' players. It doesn't take long to get to 'Z' players." The theory behind this is that people who aren't "A" players generally don't want to hire people more talented than they are. Many "B" and "C" players operate from a place of ego, fear, or insecurity. They don't want people working for them who would show them up. They want to be seen as the smartest person in the room.

If an "A" player ends up reporting to someone operating from a place of ego, insecurity, or fear, there are only two outcomes: the "A" player quits, or the "A" player gets let go for some vague performance reason. Either way, it doesn't work.

It's not about hard skills

Notice that none of these attributes are about how much the person knows about their area of expertise, or how technically talented they are. It's about mindset. You can have the talent, but without the right drive and mindset, you can fall short.

"A" players' drive and determination can make them more demanding and impatient in certain circumstances, and they can be hard to retain, but when they're empowered and partnered with other "A" players, amazing things happen.

There are a handful of "A" players I know that I deeply respect. I learn from them every chance I get. Identify the "A" players around you and see if you can grow with them.

Things To Explore

  • How AI Impacts Skill Formation is a study that examines how AI assistants can impact competence. It suggests that you should use them with caution.
  • 21 Lessons From 14 Years at Google by Addy Osmani is a good read. It's a lot of advice that very senior engineers have said before, but the list is good and concise.

Monitor Your Web Apps with Updo

If you want a basic way to monitor the uptime of your websites and applications, Updo gives you a lightweight and powerful way to do that. You can test individual URLs on an interval, use different request methods, and even build a configuration file with different settings for each site you want to monitor.

Install Updo on macOS with Homebrew:

$ brew install owloops/tap/updo

On Ubuntu and Debian, install with dpkg:

# Replace VERSION with actual version (e.g., 0.3.7)
$ curl -L -O https://github.com/Owloops/updo/releases/latest/download/updo_VERSION_linux_amd64.deb
$ sudo dpkg -i updo_VERSION_linux_amd64.deb

Or, if you have Docker, build your own image:

$ docker build -t updo https://github.com/Owloops/updo.git

If you use Docker, prefix commands with docker run:

Test a site

The basic command to monitor a site is

$ updo monitor https://example.com

This command presents a complete terminal UI that shows details about the uptime and tests:

updo terminal user interface

Press q to quit the user interface.

The default settings check the specified site every 5 seconds, an unlimited number of times. But you can override that. Run the following command to test the site 5 times, 10 seconds apart:

$ updo monitor --refresh 10 --count 5 https://example.com

The command runs, and the UI exits at the end of the fifth retry.

You can use Updo to test your APIs, too. You can pass headers and request bodies, and send POST requests:

$ updo monitor --request POST --header "Content-Type: application/json" --data '{"test":"data"}' https://api.example.com

This is a great way to test your API's health check endpoints.

Testing multiple sites

You can create a configuration file that contains settings for multiple sites and endpoints. Here's one that monitors two sites and an API endpoint. Create the file site-config.conf and add the following code:

[global]
refresh_interval = 10
timeout = 10

[[targets]]
url = "https://google.com"
name = "google"
assert_text = "google"

[[targets]]
url = "https://amazon.com"
name = "amazon"
assert_text = "amazon"

[[targets]]
url = "https://api.example.com/health"
refresh_interval = 30
name = "API"
method = "POST"
headers = ["Authorization: Bearer token"]

This file configures Updo to monitor Google, Amazon, and an example API endpoint. You can set global options like the refresh_interval, but then override them for specific targets. The name field is what gets displayed in the UI, and the assert_text field is what gets displayed in reports.

Save the file and use the --config-file option to specify the configuration you just created:

$ updo monitor --config site-config.conf --simple

When you run the command, the UI shows you multiple targets. Use the arrow keys to navigate between them.

Updo UI showing multiple targets

If you want to monitor without the UI, use the --simple flag:

$ updo monitor --config site-config.conf --simple

This time, Updo streams results back to your terminal:

UPDO monitoring:
google: https://google.com
amazon: https://amazon.com
API: https://api.example.com/health
API response: seq=1 time=1ms status=0 (DOWN) uptime=0.0%
google response from 142.250.191.142: seq=1 time=394ms status=200 uptime=100.0%
amazon response from 98.87.170.74: seq=1 time=496ms status=200 uptime=100.0%
google response from 142.250.191.142: seq=2 time=410ms status=200 uptime=100.0%

That's just the beginning. You can use web hooks when things are down, and even integrate Updo with logging tools and visualization tools like Grafana.

Parting Thoughts

  1. How do you measure up? Are you an "A" player according to the criteria in this issue? What opportunities for growth do you have that might get you closer?
  2. How fluent are you in the programming languages you work with?
  3. If you have a few websites you check, build a configuration file for Updo and get it monitoring your stuff. Use a webhook to send notifications to Slack or Discord, so you know when something breaks.

See you next month.

I'd love to talk with you about this issue on BlueSky, Mastodon, Twitter, or LinkedIn. Let's connect!

Please support this newsletter and my work by encouraging others to subscribe and by buying a friend a copy of Write Better with Vale, tmux 3, Exercises for Programmers, Small, Sharp Software Tools, or any of my other books.

You just read issue #49 of Code, Content, and Career with Brian Hogan. You can also browse the full archives of this newsletter.

Share this email:
Share on Twitter Share on LinkedIn Share on Hacker News Share on Reddit Share via email Share on Mastodon Share on Bluesky
Twitter
LinkedIn
Mastodon
Bluesky
Powered by Buttondown, the easiest way to start and grow your newsletter.