Tag: Customer Obsession

Out Of Sight, Out Of Mind

Out Of Sight, Out Of Mind

Today I came across this statement from Alfred North Whitehead, and instantly loved it as an extension of my previous post on abstractions.

“Civilization advances by extending the number of important operations which we can perform without thinking about them.”

That to me is the essence of abstractions. Not that one needn’t ever be required to dig down into the implementation details, but that the layer on top of those details enables them to be ignored to an increasing degree.

Incidentally, this is the second Alfred North Whitehead reference I’ve come across recently, the first being a mention of his book Science and the Modern World in one of my favorite podcasts. Something tells me I need to dive deeper.

Even If It’s Broke, Don’t Fix It

Even If It’s Broke, Don’t Fix It

I doubt we’ll ever learn the root cause of a particularly nasty security vulnerability recently revealed in MacOS High Sierra. But it’s fun to theorize. I’d wager it went down about like this:

  1. In the earliest days of the Darwin kernel, it was decided not to set a default root password, because it could cause usability issues for non-technical people buying Macs
  2. As a consequence, any dialogs or other interfaces that ask for login information had to have special cases built into them to not allow root as an option, or at least not to allow it if no password had been set
  3. Over the years, the number of such widgets grew, requiring more and more little special case checks
  4. The reasoning behind the decision at step one was forgotten, probably to the point where entire teams of developers didn’t even know MacOS has no default root password
  5. While building the High Sierra release, a developer (probably new and/or junior-ish) noticed an odd bit of special-case code in a library that was getting in the way of a new feature being added; a few clicks later and the seemingly unnecessary check was removed, and now the feature worked
  6. QA regression tests the release and finds no problems, because no one thought to try using the unprotected root account in various places (see #4)

Good times, Apple. I feel your pain.

Way Way Back

Way Way Back

I’ve had the pleasure of working with a large variety of technologies over the course of my career. Yesterday I was working on an interface to an old government database, without the aid of documentation, natch. After a few hours I was able to extract data from the system, but I was unable to decode it. Google is a great tool (I couldn’t get 15 minutes into my day without it), but if you don’t know what to search for you can’t find anything. Thankfully some careful guesses led me to the Wikipedia entry for EBCDIC, a character encoding developed in the mid-60s.

“Extended Binary Coded Decimal Interchange Code (EBCDIC) is an eight-bit character encoding used mainly on IBM mainframe and IBM midrange computer operating systems. EBCDIC descended from the code used with punched cards and the corresponding six bit binary-coded decimal code used with most of IBM’s computer peripherals of the late 1950s and early 1960s.”

It’s a fun thing in this industry to say you’ve worked with 50-year-old technology, but only once you’ve figured it out. Surprisingly there’s some modern tooling to interface with this particular encoding (yay Python!), so once I knew what I was dealing with it was straightforward enough. Maybe even easier than what it used to be, if this anecdote is to be believed:

EBCDIC: An alleged character set used on IBM dinosaurs. It exists in at least six mutually incompatible versions, all featuring such delights as non-contiguous letter sequences and the absence of several ASCII punctuation characters fairly important for modern computer languages (exactly which characters are absent varies according to which version of EBCDIC you’re looking at). IBM adapted EBCDIC from punched card code in the early 1960s and promulgated it as a customer-control tactic, spurning the already established ASCII standard. Today, IBM claims to be an open-systems company, but IBM’s own description of the EBCDIC variants and how to convert between them is still internally classified top-secret, burn-before-reading. Hackers blanch at the very name of EBCDIC and consider it a manifestation of purest evil.

It’s Elementary

It’s Elementary

There are really only two tasks a company must perform:

  • Make great products
  • Sell them for a profit

Each employee, no matter her job title or role, must contribute in some way to one or both of those two goals. Any other task is only a means to one of these ends; everyone involved does well to remember that.

And yes, I realize strictly speaking products and services are two different things, but for the sake of pith can we consider the latter a type of the former? Thanks.

Gimme That Foot Gun

Gimme That Foot Gun

The past couple of days I wrote about the dangers of providing too much functionality. In a fit of cognitive dissonance I now want to contradict myself and demand dangerous power when it suits my needs.

I’ve been working the past week to get a particularly gnarly application running in a set of docker containers. There are over a dozen services, plus a Rabbit queue and a database. Many of the services do not handle database connection failures in a robust way. During my testing I wanted a simple way to ensure they waited a bit before trying to connect, as the database container needs a minute or so to seed itself and get ready for connections.

Unfortunately,docker-compose does not have any form of manual startup delay feature. This is by design, as the Docker team (rightly) argues that having services intolerant to connection failure is a bad thing. However, it’s frustrating to not have the power to do the wrong thing in the short term.

Then again, it turns out it wasn’t too tough to augment my compose file with a depends_on clause that includes a health check, which is a more reliable solution anyways.

High-Powered Foot Assault Rifle

High-Powered Foot Assault Rifle

Giving a user too much flexibility can be a dangerous thing. Better to do the hard work of separating actual requirements from “desirements” (as an old government customer of mine used to say).

Yesterday’s lesson: the Perl HTML::Tidy library doesn’t handle certain UTF-8 encoded characters properly. In particular, it truncates a non-breaking space (code c2 a0) into a bare control byte (c2), which at best gives a mangled character, and at worst an invalid encoding sequence. Pass that result to another utility, and you can expect failure.

The above incident was particularly difficult to debug because the app in question does not keep edit history. I was reminded how valuable it can be to track changes over time, not just in source code, but about the data on which an application operates as well. Made me think that git might not be a half-bad back-end storage mechanism in many situations. Anyone have experience with that?

User Error Isn’t

User Error Isn’t

It happens to every developer at some point. You spend a bunch of time trying to determine the source of an urgent bug, only to find out the problem was caused by action or inaction of the user. It’s easy in that moment to be frustrated, but may I suggest a more circumspect path? It behooves a thoughtful developer in these moments to consider if the source of the user error was caused by poor design. Perhaps the button wasn’t in an obvious place, or the side effects of the command were not obvious, or the name of the feature didn’t describe the outcome. In many (even most) cases, user error is preventable with good design.

Yes it’s difficult, and perhaps impossible in some situations. But it is the high calling of the software engineer to design products in a way that a user almost subconsciously knows how to operate without error. Viewing design with this attitude saves a lot of frustration.

It might seem this is a counter argument to Not Even Mostly, but actually they go hand in hand. A user must be carefully listened to and considered, but sometimes they must also be guided into the features they really need, versus what they say they want. Do that hard work up front, and you’re more likely to have a system that minimizes the potential for mistakes.

Also, go read The Design Of Everyday Things.

Numbers Do Lie

Numbers Do Lie

The Internet is a funny place. Yesterday was the first weekday in some time that I didn’t write a post, yet I had the most page views in a single day since I created this thing. Apparently someone (or some-bot) in Canada decided to read every single post I’ve ever written. A roughly similar thing happened a few weeks ago, when a post I spent quite a bit of time on got only a handful of views, while the filler I wrote the next day got three times as much traffic. I’m not complaining, just observing that it can be difficult to predict how consumers will respond to a product.

I think there’s a lesson there for aspiring software developers (and really creators of all types). Don’t get too hung up on numbers or popularity. Don’t think less of yourself just because your app didn’t blow up like Facebook or Instagram (those guys will tell you that was luck as much as it was hard work). Simply do the best work you can.

When I decided to revive this blog, I wanted to post daily for two reasons. I figured it would draw more traffic to have more content, but more importantly, my writing muscles had atrophied and needed regular exercise. Ultimately this whole thing is for my own enrichment, but if it helps others, great.

Not Even Mostly

Not Even Mostly

Customers are a finicky bunch (they’re human, just like everyone else). That means they’re not always right, and any business practice that assumes they are is likely to fail in the long run.

Don’t hear me wrong, I’m not saying that software engineers shouldn’t listen to customers. Nor am I saying businesses shouldn’t carefully consider their customers’ demands and in certain situations give in. I’m really speaking more to an attitude of continual acquiescence. That’s not helpful for a customer who may not have the skill to evaluate what they want, and it’s not healthy for a developer when they see their professional opinions thrown to the wayside.

If a relationship isn’t a two-way street, it’s probably not worth having.