Whenever I approach a new spoken language, I’m drawn to their idioms. Expressions that when translated literally, make no sense, but often convey a large concept in a fun way. German and Swedish are famous for their hilariously odd idioms, and Brazilian Portuguese has some truly colourful great ones.
Some of my personal favourites come from the world of software development.
This is in reference to the Law of Triviality which states that disproportionate time and emotional energy will be spent on the least important matters.
The core reason for this tends to be that: people either aren’t capable of or don’t have the energy to understand the most complex aspects of a problem. They don’t want to be seen as not contributing to a project, so they focus on the low-hanging fruit of trivial problems that anyone can understand.
The term bike shedding originates from a now famous bikeshed email from Poul-Henning Kamp to the FreeBSD mailing list. After much discussion, planning, and a careful implementation of a change, there was a backlash over its most trivial aspects from people who didn’t understand any of the complexity.
The bike shed metaphor itself comes from a 1960s writing by C. Northcote Parkinson and was summarised well by Poul-Henning Kamp:
Parkinson shows how you can go in to the board of directors and get approval for building a multi-million or even billion dollar atomic power plant, but if you want to build a bike shed you will be tangled up in endless discussions.
Parkinson explains that this is because an atomic plant is so vast, so expensive and so complicated that people cannot grasp it, and rather than try, they fall back on the assumption that somebody else checked all the details before it got this far.
A bike shed on the other hand. Anyone can build one of those over a weekend, and still have time to watch the game on TV. So no matter how well prepared, no matter how reasonable you are with your proposal, somebody will seize the chance to show that he is doing his job, that he is paying attention, that he is here.
This is an unfortunately persistent problem with humans in general. As our world has become more complex, skillsets have become more specialised, meaning more works seem like incomprehensible magic to nearly everyone else. So the bits that the layman can understand, which will be the most trivial, are the bits most easily targeted for criticism.
This is a problem I experience often enough in software. When designing a complex system and presenting it to others, most criticism and feedback comes on the most trivial parts. Try designing a robust and secure authentication and authorisation system, and you’ll get feedback from everyone on the wording of the error messages and the colour of the links.
When I first heard the story of the cargo cult, I was amazed. I loved it.
During World War II, the United States used many islands in the Pacific as bases of operations for the war effort. They built landing strips and flew in cargo planes full of tinned food, medicine, vehicles, clothing, and other goods that were a wonder to locals who had never seen anything like it. The soldiers shared some goods with the locals. After the war, the armed forces left and the planes never returned. The locals missed the shipments of interesting goods. All they knew is that that when the large bird-shaped things came, food and supplies came too. So they built airplane-shaped structures and control towers out of sticks and whatever they could scrounge and waited for all the cargo to return. Of course it never did.
This same concept is surprisingly pervasive in many industries, especially software development. Open source software is a great thing for many reasons, not least of which is the ability to learn from how others have done things. A downside to this can be the propagation of practices by developers who want to achieve a similar goal, but don’t understand the code or tradeoffs behind the solution they copied.
You can easily detect cargo culting when you ask someone why they did something and the answer is something to the effect of: “because I saw other people doing it.” I won’t for a minute pretend I haven’t done this. I think we all have. And eventually when our cargo-culted solution breaks and we have to fix it, we have no idea how it works or what we’re doing and we’re stuck…and we learn a lesson.
When you have a task to do, but get side-tracked doing related tasks that you feel like are pre-requisites. They’re often not strictly necessary, but you do them anyway.
Say you have to correct a UI typo an app you haven’t touched in ages…
- You clone the repository
- You decide to Dockerize the application rather than install dependencies on your system
- Update the README for new Dockerizing approach
- Update outdated dependencies, some of which require some code changes
- Apply a linter/formatter to the codebase to correct inconsistencies
This goes on for half a day before you realise your five minute project has got out of hand. You’ve spent the morning yak shaving. This list was easy to come up with since I find myself doing exactly this list too often.
It’s a hard problem since the tasks do add value and it feels good to work on them, but they are not what you set out to do and they wreak havoc with your estimates.
This clip from Malcom in the Middle is textbook yak shaving:
There’s no cut-and-dry answer to it. I usually allow myself to do a little bit of yak shaving, get on with the task at hand, and create issues/tasks to follow-up on the stuff I noticed along the way that should be handled.
In my early days with software, I couldn’t wait to upgrade to the latest versions of everything. Service Packs, patches, major new versions. I wanted to be running the latest and greatest versions of every piece of software I could on day zero.
At work, our boss and tech lead, who had been at this a lot longer than me, took a more conservative approach. We wouldn’t upgrade major software like our database or operating systems without at least one service release being available. We wouldn’t adopt new major versions of language platforms until there had been a service release either. This made me a little sad, but I went with it.
More than a decade later and I’m now completely on board with this. And there’s no zealot like a convert, so here I am writing about it.
I’m currently working a project that will put my Raspberry Pi 3 B to work as an embedded system running primarily on battery power. Naturally one of my goals became to reduce the power consumption of the Raspberry Pi as much as possible to make the most of battery life. I saw tips for disabling the activity LEDs, switching off HDMI, and a few other things, but none seemed to move the needle at all on power consumption. It still used about 140 mA (0.7 W) at idle.
Then I checked if you could disable the USB hub since I don’t need it. After disabling the USB hub the power consumption dropped to 20 mA (0.1 W). That’s a huge power savings.
One caveat with this approach is that it also disables the Ethernet controller. So if you need wired LAN, don’t do this.
The quick way to disable the USB hub:
echo '1-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
This won’t persist across reboots, so I wrote a script to do it for me and set it to run on startup via
/etc/rc.local. In case I need to do some manual fixes on the device with a keyboard and/or Ethernet, I have the script check if any USB devices are plugged-in or if the Ethernet cable is connected. Only if nothing is connected will it disable the USB hub. So if I need a keyboard, I just plug it in and power cycle the Pi!
#!/bin/bash # With no devices plugged-in, there will only be "devices" at "1" and "1.1" # If any devices beyond that are detected, such as 1.2, don't disable USB. cat /sys/bus/usb/devices/**/devpath | grep -Eq '^[1-9]+\.[2-9]' if [ $? -eq 0 ]; then echo "USB devices attached. Aborting." exit 1 fi # Disabling the USB controller also disables Ethernet, so don't do that # if there's an Ethernet cable plugged-in. if [ `cat /sys/class/net/eth0/carrier` != "0" ]; then echo "Ethernet cable is plugged-in. Aborting." exit 2 fi echo "Disabling USB interface" echo '1-1' > /sys/bus/usb/drivers/usb/unbind
I like to keep my git commit history clean and concise. If each commit is a clean package of atomic changes, a larger pull request is easier to review commit by commit. Conversely, if you have a history littered with fixes and changes, reviewing each commit doesn’t work.
git rebase -iis a great way to re-order commits, drop commits, or merge commits together with
fixup. The only difference is that
fixupdiscards the commit message whereas
Consider a workflow where you’ve added a feature to your app and commit this change.
git add app/ git commit -m "Add feature"
Now let’s say you notice you forgot your new test files to this commit so you
addthem. At this point you can easily do a
git commit --amend --no-editwhich will amend the previous commit and use the original commit message. Easy!
But what happens if you’ve made a commit since then that has nothing to do with this feature? You could just make a separate commit:
git add test/ git commit -m "oops, forgot the test files for the new feature"
A better way is to use the
git logto get the hash of the commit you want to amend. Then commit your amendment like so:
git add test/ git commit --fixup=hash_of_commit_to_amend
This creates a normal commit with a special message. In this case it would be
!fixup Add feature. Now, run
git rebase -i --autosquashand you’ll see the magic.
pick f0f6a56 Add feature fixup 7897d4d fixup! Add feature pick 03b9a80 Fix unrelated bug
Git recognises the
!fixupcommit and places it after the commit to amend and automatically sets it as a
fixup. Now when you quit the editor, history will be re-written.
By default when you use
git rebase -i --autosquashit only shows commits that have happened since your last push. So if you use
--fixupon a commit already pushed to the remote, it won’t do anything. You can work around this by rebasing farther into the past, but that will then require a force push and all the usual caveats there. If your branch history needs that much re-working, you might just want to create a new one.
This past summer I treated myself to building a new PC. I hadn’t built a PC in over ten years ever since I got a MacBook Pro that could do everything I needed for both work and personal use. I’ll skip the part where I fall out of love with MacBooks and sell my 2017 MacBook Pro.
After watching so many YouTube videos about PC builds, and wanting to do some PC gaming, I had to build one. So I built a modest system, trying not to go beyond the point of diminishing returns for components. For example, the i7-8700K is twice the price as an i5-8400. Is it twice as good for what I’ll be doing? Highly doubt it.
I installed Windows 10 and Windows Subsystem for Linux. I have to say, Microsoft did a truly impressive job there making that work. It worked really well. The problem is I just didn’t enjoy using Windows, it was sluggish at times, and I was spending all my time in WSL anyway. So I wiped it all out and installed Arch Linux.
I hadn’t used Linux on the desktop since Gentoo back on my Dell Latitude D400. That was back circa 2005. Gentoo was a great distro for get started with Linux since you had no choice but to learn how the whole system is put together. So if something goes wrong, you know how to help yourself through it and you learn a lot along the way. The other factor I valued is that your system would only have software you asked for and nothing else. I don’t like bloat, so Gentoo was perfect. But for a new install I wasn’t interested in Gentoo, as compiling everything from source is just a waste of time. Arch looked like the worthy successor. It’s a roll-your-own OS like Gentoo with rolling releases and an enthusiastic community; the value of which should never be underestimated.
After having Arch Linux setup for some weeks, I’ve compiled a list of packages that I had installed and why. So next time I setup Arch I’ll have a good list of packages for my base system. I’ve left off the stuff that’s quite obvious for me to install straight away like a web browser, editor (Sublime Text), and things like that. I’ll probably update this as I make changes.
With my Dell Dimension XPS T450 ready hardware-wise, I needed to get some operating systems installed. My ideal setup is triple-booting Windows 98, NT Workstation 4, and 2000 Professional. This isn’t as straight forward as you’d imagine and it took me more than one total reformat to get it working. This is a tale of many, many failures finally leading to some success.
Fetching the Magic Trackpad 2 battery level from the command line and logging it to a file!
When I moved to Germany, I brought a bunch of electronics with me that I had acquired in Japan, Thailand, and the US. Fortunately they all had switching power supplies, so the voltage and frequency difference (110v @ 60 Hz vs 220v @ 50 Hz) wasn’t an issue. The issue was the plugs themselves, so a solution was required.
Recently I’ve been having a lot of 90s nostalgia, especially related to technology. I fully blame YouTube channels like LGR, 8-Bit Guy, Phil’s Computer Lab, Adrian Black, and a dozen others I’ve spent countless hours watching. Plus it’s part of getting older; you romanticise the past.
I started thinking about what hardware from the past I felt the most affinity towards. It took me no time at all: I wanted a Dell Dimension XPS from the 90s. This is my history with Dell.
You’ve got a Ubiquiti EdgeRouter and an Active Directory domain. Here’s how you make them play nicely together.