nonsense
"Bring me solutions, not problems"
There’s a classic piece of advice for managing upwards: “bring solutions, not problems.” The simple explanation is that your manager hired you to solve their problems, so if you’re just bringing their problems back to them then you aren’t providing any value. Instead, value comes from you spending energy thinking deeply about their problems and identifying a handful of solutions along with a recommendation. That lets them think about three options rather than having to reason through a potentially infinite greenfield, and spares them from context-switching into your problem space. Like all good advice (for example, “don’t reinvent the wheel”), I both theoretically agree with it and practically hate it.
Continue reading →Who killed the web designer?
Alternatively, “April naively wanders into gender politics and says a lot of dumb things”
Heather Buchel’s article It’s 2023, Here is Why Your Web Design Sucks traces the death of the job title “web designer” and the subsequent rise of the “frontend developer” role. She writes that design, being distinctly feminine-coded, didn’t appeal to the men entering the web programming field and that their disinterest de-emphasized that expertise until it disappeared. She also links to a separate article, Tailwind and the Femininity of CSS, that explains how few people bother learning CSS in depth as being due to its proximity to the feminine design role. Friends, I had a strong reaction to these articles. How can people I am so alike have drawn such different conclusions than me? Did I just miss this shift in the industry? Or worse, am I part of the problem?
Continue reading →A better S2 viewer
I’m excited to share my new S2 Viewer! After struggling with all of the others (and the best one from Sidewalk Labs being taken down) it was clear I needed to make my own.
Left click to select a cell. The level is based on your zoom, or use the drop-down in the top right
to lock a level. To see information about a selected cell, right click on it. You can also paste in
a list of cells (like 5490ce5,5490d1f,5490cdd
) and it will display them on the map. And it also
supports z/x/y
tiles!
This works by transpiling the Java S2 library with j2cl. While GWT had its problems, the core idea was fantastic and j2cl takes all of the good and none(-ish) of the bad. You can see the implementation in my repository.
Let's talk about the technical coding interview
As an interviewer, a mentor, and now a hiring manager I have put a lot of time and thought into the technical coding interview: the practice of asking candidates to solve a programming question on a whiteboard (or in CoderPad.) Rather than writing yet another “cracking the coding interview” guide, of which there are already a million, this post tries to focus on the broader picture. I’ve broken it down into several sections.
- Reasons to listen to me, reasons to ignore me
- Why do companies keep giving these types of interviews?
- Interviews, from the interviewer’s perspective
- April’s theory of interview prep
Incomplete and incorrect, part 3: I learned some things
This follows part 2 of An Incomplete and Incorrect Guide to the Kubernetes Ecosystem.
Five months have passed since my last post, suggesting I have learned five months worth of knowledge. Unfortunately, I think I’ve gained one month of knowledge and used the remaining four months to become a luddite.
Continue reading →Incomplete and incorrect, part 2: logging in Kubernetes
This follows part 1 of An Incomplete and Incorrect Guide to the Kubernetes Ecosystem. I still don’t know anything, but with a day of logging experience under my belt I’m prepared to pretend I do.
Have you ever heard the story of the paperclip maximizer? The theory goes that, if an intelligence’s sole purpose is to make paperclips, it will do everything possible to make more paperclips. That “everything” might be quite undesirable from a human perspective. Humans contain plenty of atoms that can be used to make paperclips, so such an intelligence would probably try to kill all humans. Similarly, the intelligence would likely also try to destroy Earth, because Earth contains lots of buried material that could be turned into paperclips. Overall, seems kind of bad.
While it remains to be seen if artificial intelligence will be so myopic, it turns out that even non-artificial intelligence is capable of such atrocities. For one example, consider the folks pushing Elasticsearch as the solution to all your Kubernetes logging needs. Given a goal (“make a powerful way to collect and filter logs”), they executed so relentlessly that the solution is so powerful and featureful and enterprisey that it’s unusable by standard humans. It’s a bit unfortunate.
But before we get there, let’s step back for a second and figure out how Fluentd, Fluent Bit, Elastic, Grafana, Kibana, Filebeat, Logstash, and Loki all relate.
Continue reading →An incomplete and incorrect guide to the Kubernetes ecosystem
… from someone who doesn’t know anything.
I’ve been using Kubernetes professionally for about seven months, which makes now the ideal time to write this post. There are only a few known unknowns, enough known knowns that Dunning-Kruger is in full effect, and presumably the space of unknown unknowns remains approximately infinite (but, luckily, by definition I see no evidence of that.)
This post is flippant and unfair. The fact that any of this works at all is a miracle, and is only possible thanks to an army of maintainers (many who are volunteers and some who no longer even use what they're maintaining), inheriting constraints and contexts that I can't even imagine.
Full disclosure: I once tried to join the Kubernetes core team and was rejected. I leave it as an exercise for the reader to determine whether that was for the best.
The first thing to know about Kubernetes is that it’s a multiplier. If you can make some software run in a container on one machine, you can easily make that software run on 1,000 machines. On the other hand, if you currently have 1 problem (presumably what you’re using Kubernetes to solve), tomorrow you will 1,000 problems.
Anyway, let’s work our way up the stack.
Continue reading →The abbreviated guide to WebGL
This is a triangle.
It lives in a viewport.
The viewport has a coordinate system named clip space.
You write a program, called a vertex shader, to convert your crazy coordinate system (called view space) into clip space.
But wait! Where did the color come from?
Continue reading →Letters on California
A year and a bit ago, I left California and learned how difficult it is to leave. Of course, I’ve been outside California before. And, of course, leaving is as easy as sitting in a moving vehicle and waiting. And, obviously, I came home. But, though a fish learns about water the first time they leave it, it seems I only learn about California the millionth time I leave it. My respect for fish only grows, but I digress.
Driving across the border from Tahoe into Nevada, I begin to experience emotions. “I’m somewhere!”, I think. “I’ve done something!” And that’s a good feeling, but there’s also an unmistakable sense of loss. Shortly before crossing, looking out the window yielded breathtaking alpine views. Shortly after, looking out the window yields a revolting casino. I suppose I should be thankful for that casino, because at least it’s a warning: within minutes I’ll be driving through Stockton, Nevada (though the locals call it Reno.) But, for all of my negativity, I love Nevada. How can this view of Battle Mountain, a gorgeous mountain range I used to sneer at, only cost $19,000? How can Great Basin National Park, an island in the sky with aspen woodland, deer, and the cutest specimens of rodentia, be so deserted? Valley of Fire, Red Rock Canyon, you just can’t go wrong.
And, as I continue along 80, crossing into Utah, Wyoming, and Colorado, my wonder only grows. Could it be true? Could I be happy living here? It certainly seems so. If I hadn’t been born in California, I would undoubtedly have been born in Bend, Bothell, or Boulder. There is no other way to explain the acute sense of home I feel in those places. Even the strip malls feel so familiar. But, I always leave.
Blinded and terrified in a snowstorm at the Eisenhower tunnels, gasping in surprise at the beauty and calm of Grand Junction, watching sunset over the Great Salt Lake, yearning to see Battle Mountain from another set of angles, I can’t shake the feeling that I am making a great mistake. Every passing mile holds its own surprise, every turn reveals a slight change in geology. Why am I passing all of this? I can’t count the numbers of photos I’ve missed because of a stubborn refusal to stop. Is the allure of sitting on my couch really so strong?
As I pass the casino again, heading into California, it becomes apparent: there are no further discoveries in this trip. But while it feels like that should be a bad feeling, there’s an undeniable amount of comfort. Suddenly, the drivers get worse (half choosing aggression, and half choosing cluelessness.) It hits me: these are my people. Their driving may be a crime against humanity, but I understand what they’re doing and I fit right in. More importantly, after one thousand miles of clouds, the clouds part and Tahoe reveals itself glistening. A few days before I had been shivering in my car, but now I can feel the warmth all around me. I’ve heard that home is a time and a place, and returning to California on the day of the Superbowl makes me realize: home is rush-hour in my car. I don’t understand it, and I wish I didn’t feel this way, but I am truly, finally, home. And I know why I’m back.
2020 in photos I wish worked
Gstreamer segfaulting randomly
Today I changed music providers and was surprised to start getting segfaults from my Python program with no error message. Thinking maybe something was wrong with the urls, I tried a nice minimal example and that worked fine. Hm.
My program, a smart home music player, has both a GLib loop and a gRPC loop. After whittling down
the Gstreamer code as much as possible I learned nothing beyond the failure being triggered by
playbin.set_property('uri', url)
. Not even setting the environment variable GST_DEBUG=4
would
coax it into telling me anything. Finally I moved the call to the very start of the program, prior
to even setting up a GLib loop and was pleasantly surprised to see
std::runtime_error what(): Unable to read configuration
followed by the segfault.
What indeed.
Google searches revealed
a Debian bug report in some other media
player with no fix or workaround, but the report did have lots of speculation that the cause was a
library I’ve never heard about named libproxy. Braver souls
than I might have looked into why Gstreamer was trying to proxy my requests, but as a lazy bum it
seemed easier for me to figure out how to neutralize libproxy by disabling it or creating whatever
configuration it wanted. Searching for the string "Unable to read configuration"
in that library’s
code presented
several hits, so it
seemed like the bug report’s speculation was correct. In particular,
config_sysconfig.cpp
and
config_envvar.cpp
both looked like promising candidates for being the root cause
(there’s also a KDE config, but as I don’t use KDE that one seemed unlikely to help.)
Having come across config_sysconfig
first, I dutifully put PROXY_ENABLED=no
into
/etc/sysconfig/proxy
, ran my program again, and was immediately greeted with another crash.
Fine, maybe config_envvar
is what’s running. Initially dismayed to see no PROXY_ENABLED
equivalent, the NO_PROXY
environment variable used inside get_ignore
looked promising but
confusing. After further tracing through the code I found that the magic incantation was
NO_PROXY=-
and now everything works!
What a nuisance.