For an engineer, the sharing of thoughts and ideas can be more important than the implementation. By sharing thoughts and ideas in a coherent manner, you are able to solicit feedback and harness the collective wisdom of a wide variety of people with vastly different experiences and background.

Collecting rich and thoughtful feedback starts with concisely presenting your ideas in an appropriate medium for your audience. Having a wide selection of tools in your toolbox for maximizing your expressiveness helps to greatly increase your chance of engaging your audience. A highly engaged audience is more apt to provide feedback because, at very least, they were paying attention.

Learning Style Myths

We’ve likely all heard that there are various learning styles. The claim I hear most often is that folks are “visual learners”. It is the general consensus that this is nonsense. There may be preferences in how information is presented, but that does not make any one “style” more effective than another.

In my experience, it’s always helpful to provide visual aids. Visual aids can help take an abstract idea and make it a bit more concrete. In some cases, it would simply take too many words to describe a system that could otherwise be presented as a simple diagram. I don’t think this is about learning style, and is instead about the clear and cogent presentation if ideas. That is, if your idea or concept has a lot of interconnected elements, it’s likely going to be helpful to show how those elements are connected. Otherwise, you place the burden of visualization on the audience. They are left to keep a mental map of what you’re explaining.

A good example of this would be directions. That is, directions from some point A to another point B. If the points are close, and the directions are straightfoward, then a simple explanation can work – “you can find your car keys on the kitchen table”. In this case, it’s not necessary, and likely overkill to create a map.

Conversely, if you are giving directions from downtown Chicago to downtown Manhattan, you’re likely going to want to present a visual aid in the form of a map accompanied by a list of steps. Luckily, technology has caught up with our needs in this area, and we have a fully automated, animated, turn-by-turn presentation offered to us through our smartphones and standalone GPS devices (do folks still have standalone GPS devices?).

Everyone is a “Supplemental” Learner

What do I mean by “supplemental” learner? Well, not everyone has the gift of sight. Similarly, not everyone has the gift of hearing. There are folks who want to consume your content that may be different from you. The best thing that you can do is concisely describe your thoughts and ideas with as many supplemental artifacts as are warranted to fully express yourself, and to the extent required for your audience to understand.

In my experience, this means that you should consider multiple media for presenting your ideas. Seldom is a single medium enough. A long, wordy document can be greatly enhanced with some visuals. Similarly, a single visual usually cannot stand on its own – it requires some text to help explain the context.

The bottom line is that the more ways you can present your thoughts and ideas, the more likely you will be to engage your audience and solicit feedback.

Tools of the Trade

A workbench with tools

Here are some of the tools that I use in order to maximize how effectively I can communicate:

  • Lucidchart – provides an excellent diagramming experience
  • – allows you to create diagrams as PNGs that can be edited again. This is great for images being checked into source control. You can also copy from Lucidchart and paste into
Screen Capture / Annotation
Image Manipulation
  • Adobe Photoshop – the undisputed king of image editing. Great for compositing images
  • – a very capable alternative to Photoshop, albeit not as full-featured
Video Editing
  • Adobe Premiere – a great video editing platform. There are tons of free alternatives, but I personally prefer Premiere
  • Adobe After Effects – great for motion graphics, callouts, and other fancy enhancements that can really elevate a video (see Prezi below for an alternative)
  • Kdenlive – an open source alternative to Premiere
  • Microsoft Powerpoint – this is pretty standard fare. You should get good at using Powerpoint, but please, don’t just read your slides.
  • Prezi – this could also fall under the Video Editing heading. Prezi allows you to create more complex animations for truly engaging presentations. It even supports video overlay, so you can have motion graphics without After Effects!

Workbench photo by cottonbro from Pexels
Cover photo by Christina Morillo from Pexels

The “Opaque Box” Data Pattern

The “Opaque Box” Data pattern is an anti-pattern. It’s an anti-pattern that I have seen time and time again throughout my 25+ year career.

This anti-pattern starts with a highly optimized data querying and storage facility – this could be a relational database, or something schemaless; it doesn’t matter. From there, the immense complexity, years of software evolution, and the remarkable flexibility of that datastore are ignored and the pattern effectively says, “nah, I’m good”, and it takes the important bits of the data, encodes it in an opaque binary structure, and unceremoniously shoves it into the data store.

A gif of a car in a crash test slamming into a barrier and being destroyed in the process
Here we see someone trying to query a datastore where the important bits are in a binary blob.

In my experience, this pattern is usually employed by folks that just learned about structured data transport formats like Protocol Buffers, Thrift, or Avro. Now, these formats aren’t inherently bad; they’re wonderful for communicating across services, either directly or via a message queue. They can even be useful in databases under the right circumstances (primarily starting with choosing to store them in their respective JSON formats).

If, however, you look at these formats and think, “wow, look at how small the data is when it’s encoded as binary”. You’re on the right track… for data transfer purposes. If you think the same thing, then take that opaque, binary-encoded blob and shove it into a database where you might want to query for the data, you need to take a step back and reevaluate your architecture. This is the equivalent of filling your pantry with all kinds of boxes and cans of food, then painting all of the boxes and cans the same color so you have to open each one to find out which one contains the Cheerios that you’re looking for.

Three nondescript cans, all black
You you can see a can of paint, a can of motor oil, and a can of soup. Choose wisely.

I have seen this anti-pattern employed on more than one occasion. In a recent example, the data stored in the binary blob had a strict schema which required migration if any changes were made. A migration of tens of millions of records. You know what’s really good at storing data with strict schemas? A relational database. Want some flexibility in stored data to avoid constant migrations? Maybe consider a schemaless database like CouchDB or MongoDB.

The reality is that sometimes engineers want to build complex solutions to solve simple problems. However, it’s been my experience that engineers should always, without exception, be looking to solve any problem with the most simple, straightforward approach that meets the requirements and delivers business value.

Being pragmatic includes thinking about the long term consequences of your decisions. Don’t be the engineer that paints all of the boxes and cans the same color.

Cover photo by Ryanniel Masucol from Pexels

The Experience Portfolio

This is a story about success. This is a story about failure.

You see, I’ve always felt that even in failure (especially in failure?) you gain a monumental amount of insight, data, and above all, experience. It’s through this experience that, from the ashes of failure, success is born.

Experience is what you get when you didn’t get what you wanted.

Randy Pausch

This story is about the experience on the ground floor of a tech startup. A tech startup that was founded by capable and talented people, but one that also failed to see any real financial success. For the sake of this post, they’ll call this startup “Unicorn” (any relation to a real company is purely coincidental).

Recipe for Success

Unicorn was founded by a few folks that had seen a startup exit strategy succeed. Flush with money from the previous venture, Unicorn was bootstrapped by the founders. They recruited engineers that helped make that previous venture successful and set out to build The Next Big Thing™.

Given the success of the previous venture (as measured by it being acquired by a larger company), the founders were certain that they had a recipe for success. They had themselves, the original founders of the acquired company, and the original engineers! What’s more, they had funding – unlike the first time around.

With these critical resources, Unicorn laid out a product vision: create a product that allows anyone to create Widgets – not just Widget Engineers. It would revolutionize the Widget industry with one simple question: “What if anyone could create Widgets?”

The idea was compelling – what if they really could democratize Widget creation? What if they could lower the barrier of entry and enforce best-practices for Widget creation? Certainly, anyone with a brain would see the value of this; Widgets are everywhere!

Widget Studio 1.0

Armed with a product vision and the required capital, they set out to create Widget Studio. It would be a graphical Windows desktop application with drag-and-drop Widget composition. They worked tirelessly to build complex Widget composition screens while trying to focus on creating an Alpha Widget. The Alpha Widget would be the first Widget that Widget Studio could create.

They had Business Analysts (BAs) who were intimately familiar with using Alpha Widgets. Surely if you’ve used an Alpha Widget, you should be able build one. They worked closely with the BAs to reduce friction in the Alpha Widget creation.

As time progressed, the complexity of the Alpha Widget began to emerge. There were hundreds of sub-Widgets that needed to be glued together. They needed to introduce the concept of Widget Libraries to house all these sub-Widgets. The complexity continued to increase. They soon realized they needed to manage different versions of Widgets and support concurrent Widget-builders. They needed to streamline the creation of the Widget based on the Widget Studio design. Where do they store Widgets once created? How do people access their Widgets?

Undeterred, the engineers moved forward and created clever abstractions over the Widget creation process. The abstractions were a bit leaky; you needed to understand version control and component libraries, but it was still manageable. They were getting close to having a very basic Alpha Widget.

The Runway

Aircraft on a runway

Getting to the point that they had a very basic Alpha Widget took much longer than they expected. There was an expectation that creating a complex desktop application (which nobody had ever done before) would be secondary to solving the problems of the Widget domain.

Having bootstrapped the company, the founders were, counter-intuitively, not apt to be conservative in their spending. There were more C-Level executives than engineers in the early days – and they were earning C-Level salaries. Blinded by their past success, the founders assumed throwing money at a product would get it to market faster. Additionally, they failed to consider what a Minimum Viable Product (MVP) should look like; or, at least, made the MVP scope way too large. They failed to follow an evolutionary process – get something out the door, then iterate. They made tons of rookie mistakes.

Having underestimated the effort and the cost, they realized that they were running out of runway. What once was a group of passionate engineers focused about bringing Widget creation to the masses, soon devolved into a toxic social experiment. There was finger-pointing and accusations of people “not working hard enough”. There was mandatory unpaid overtime. There was a transition from strategy to panic.

Sand Hill Road

What do you do when you’re running out of runway? Try to build more runway, of course! Instead of working to understand their product, the market fit, or in any other way solicit honest feedback, they took a trip down Sand Hill Road.

For the uninitiated, Sand Hill Road is a road in Silicon Valley which is rich with Venture Capitalists (VCs). Obviously, if they were going to build more runway, they just needed a cash infusion. Further, their confidence in their product was so high that that they were certain there was no way that any VC could say “no”.

Well, what they found out is that if you build a product and haven’t actually tested the market, it’s kind of hard to get VCs to back you with their money. Why would they? You didn’t perform the bare minimum of due diligence to determine whether your product could be a success; why would they trust you with their money?

After metaphorically knocking on every door on Sand Hill Road, they were at a dead end. No money. No runway. No options.

What followed was more in-fighting and finger-pointing. The intense workload of trying to get a product off the ground combined with being met with continued disinterest from the VCs had taken its toll.

Because it was clear that the ship was sinking engineers and BAs started to leave. Those who remained tried every possible avenue for capital infusion. But, as time ticked by and payroll had to be made, it became clear that the runway was ending, and the plane was going to crash.

Ultimately, the plane did crash and what was once Unicorn, the starry-eyed startup with ambitious goals, became a toxic, burning, husk of a company.

From the Ashes

A lot of time and energy went into building Widget Studio. Many sleepless nights, many twelve- to sixteen-hour days, and a heaping helping of stress; all for what? To build a product that nobody will ever use? That’s a fate worse than death for most engineers.

While the product was a failure and the company ultimately dissolved, it was not a failure. Sure, the product may have been a failure, but the experience was not.

When you spend so much time building something, it’s easy to get blinded by what might be. It’s easy to convince yourself that you’re the next Google. It’s easy for people to see your product and say that it’s the greatest thing they’ve ever seen (if they don’t have to back up the sentiment with money).

All of the trials and tribulations lead to a deep-seated knowledge of what not to do. The Unicorn team learned some tough, but very valuable lessons about due diligence, product market fit, project and budget planning, and a whole lot more.

You see, every time you stumble, you learn how to avoid the same mistake in the future. It’s this process which builds your experience portfolio and informs your future decisions.

While not every venture will be a success, it’s important to learn from your failures. If you do that, you will never truly fail.

Cover Photo by Filipe Delgado from Pexels
Runway Photo by Maria Tyutina from Pexels

Git Signed Commits in Windows and WSL

Developing on Windows 10 has been a joy since the release of Windows Subsystem for Linux (WSL), however straddling the line between Windows and Linux can sometimes cause friction.

With the steps outlined below we can resolve the No secret key error that can sometimes pop up while signing commits from Windows while also having GPG setup with a passphrase (which would be silly not to have, right??) in WSL.

My setup is as follows:

  • Windows 10
  • WSL v1
  • Git 2.28
  • GPG 2.2.21 with a key that has a passphrase
  • IntelliJ IDEA (but this probably applies to other Windows IDEs)

The Error

When I’m working from my WSL console, I can easily create signed commits. My keys are stored in ~/.gnupg and everything works a treat. However, when I try to create a signed commit from IntelliJ in Windows, I get the following message:

Commit failed with error
	gpg: signing failed: No secret key
	gpg: signing failed: No secret key
	gpg failed to sign the data
	failed to write commit object

When performing the same commit via the WSL console, I would get a passphrase prompt, and the commit would succeed if I enter the correct passphrase:

I didn’t get a similar prompt in IntelliJ, so it became clear that I needed a Windows option for entering my passphrase. I already had gpg installed for Windows, but it was command line driven and I suspect there’s not a straightforward way to communicate to IntelliJ that a passphrase is required. I also didn’t want to wrap gpg and store my passphrase in cleartext (because that’s like a security mullet – vault door in the front; screen door in the back).

The Fix

The quickest, most secure, way to get this working would be to install Gpg4win and import my gpg keys from WSL. So, to do this, the first task is to export my keys so they can be imported. From WSL I just drop them on my desktop:

gpg -a --export-secret-keys > /c/Users/emerle/Desktop/gpgkeys.asc

Once this is done, you can import these into the Kleopatra application that comes with Gpg4win. Be sure to permanently delete that gpgkeys.asc file – it has your private key(s) in it! Once you finish the import into Kleopatra, you’ll have something like this (but less blurry)

Now, the only thing left to do is tell git to use Gpg4win. From the Windows version of git, you set the gpg.program

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

Now when IntelliJ uses the Windows version git to perform the commit, it will use the defined gpg.program. In this case, we should see our passphrase prompt when we try to commit:

Because you added this setting to your Windows git configuration, this shouldn’t interfere with your WSL configuration. Now you can seamlessly commit from either Windows or WSL with a GPG signature!

Happy developing!


There’s this widely accepted theory in science called Evolution (and, no, a scientific theory is not the same as your uncle’s “theory” that chipmunks are stealing his WiFi). The high-level idea behind this scientific theory is that every organism undergoes random mutations. Some of these mutations may be beneficial, detrimental, or immaterial to the survival of the organism. When a mutation is beneficial such that it gives the organism an advantage over others for a shared set of resources, that organism tends to thrive.

We can take this concept of evolution and apply it to software engineering (though on much smaller time scales). To do so, we start with the smallest unit of work that provides tangible value. The Marketing and Product folks like to call this the Minimum Viable Product or Minimum Viable Experience. For the sake of the analogy, we can call this Generation Zero (G0). This is our single-celled organism that’s not capable of much, but it still constitutes “life”.

For G0 to be useful, it must be able to interact with the outside world. See, much like in the classic Evolutionary Theory, we need feedback. Our feedback won’t be life-or-death (although many ideas have died in the zeroth generation); it will be in the form of user feedback. How well did G0 meet our goals? What are the friction points? Are users getting confused and not following our calls to action? We can collect all of these metrics through innumerable mechanisms; the important idea, however, is that we delivered something and we’re gathering feedback.

Armed with this feedback we can now start to imagine what Generation One (G1) is going to look like. We build upon some of the simple ideas required for G0 and extend them in directions that we feel will make the product or service better. This may mean adding extra features or widgets, or creating a basic version of your service as an iOS and/or Android application, or tightening up your deployment strategy, or scaling out in the cloud, or whatever will bring more business value. After all, business value is the one true goal (it’s worth noting the value may not be monetary!).

Great! We now have G1 (our multicellular oganism) and it’s been deployed and we’re collecting feedback. If there were any UI/UX changes, you may get some very loud negative feedback like Snapchat, Twitter, Netflix, Google, Spotify, etc. But feedback, positive or negative, is like gold. This is the equivalent of fitness testing, or “survival of the fittest”; you are seeing whether the “random” mutations were beneficial, detrimental or immaterial.

As you continue through further iterations, you will begin to shape your product or service. Your single-celled organism will evolve, growing more complex with each iteration. As your product or service asymptotically approaches completion, you’ll try new things (mutations) and push them out for feedback (fitness testing) . You will continue to hone the parts that work, and discard the parts that don’t. Eventually, you will end up in one of two places:

  1. You’re at the top of the food chain
  2. You’re eaten by an organism higher on the food chain

Regardless of outcome, in order to fail or succeed, you must first “do”. This sounds vaguely like something Yoda would say, but analysis paralysis is real and can cause you to stand in one place and never make any tangible progress. Get your ideas out into the wild, get feedback, iterate and improve. You may get eaten along the way, but you also may end up at the top of the food chain. Either way, you’ve gained something that nobody can take away from you: experience.


Evolution logo: Johanna Pung / CC BY-SA

Show Me The Code

The Proof Is in the Pudding

I’ve always hated that expression.  What does that even mean?  The proof of what is in my pudding?  The original expression was more along the lines of “the proof of the pudding is in the tasting/eating”. Idiomatically, we all understand the abbreviated version to mean, “I’ll believe it when I see it” or in general, that the value, effectiveness and even existence of something cannot be validated until it is tested. 

Show Me the Code

In software engineering we have a similar, albeit less abstract, expression: “show me the code”.  I’m sure there are similar expressions in other professions.  I know there was an expression in the movie Goodfellas that was similar in its unapologetic tone (I’ll leave identifying this expression as an exercise for the reader – it’s a great movie anyway). In the software world, however, what we’re trying to express is that an idea, diagram, proof-of-concept, and basically anything that is not actual production code is, well, “worthless”.

Okay, I was being hyperbolic with “worthless”.  There is a ton of value in all the things that I mentioned, but that value doesn’t materialize into business value until those things are expressed as functioning production code. 

Talk is cheap. Show me the code.

Linus Torvalds

Do you have a brilliant idea?  Great; show me the code.  Do you have an academic paper extolling the virtues of some process? Great; show me the code.  Have you put together an architectural diagram?  Great; show me the code.

The 90/90 Rule

The 90/90 rule, is a humorous observation attributed to Tom Cargill of Bell Labs in the 1980s:

The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.

 Tom Cargill, Bell Labs

What I’ve seen time and time again is the most talented engineers are hyper-engaged and focused early in a project, for the “fun stuff”.  This might include playing with a new language, library, or platform.  It might mean spinning up cloud resources and building out a cluster.  It may mean tearing open some hardware and reverse-engineering it.  It may mean working some magic to performance tune some questionable part of the system. In short, it’s stuff that’s new and novel.

You see, engineers get bored easily.  We don’t want to spend time doing the same thing over and over; we need shiny new toys to excite the neurons in our brains.  Because of this, our excitement tends to wane as projects progress.  What was new and exciting becomes boring and stale.

Once the novelty wears off, engineers get an itch to move on to the next shiny new toy.  They don’t want to be tied to some project that’s entering the dreaded “maintenance mode”.  They don’t want to be answering user questions or writing documentation or convincing management that component XYZ needs to be refactored, so development starts to slow as engineers divert their energy to more exciting projects.

Show Me The (Finished) Code

With software, nothing is ever truly done, we just asymptotically approach zero features and defects.  But there is a version of done where we’ve met our business requirements and provided peak business value.  This is just before we reach the zone of diminishing returns.

An image showing the relationship between work, time and business value.
Fig 1 – The relationship between outstanding “work” and business value over time

This is probably best illustrated by the expertly drawn diagram above (Fig 1).  As the amount of “work” to be done (features to be implemented/outstanding defects) decreases, business value (ideally) increases. Eventually, over time, we stop producing additional business value and enter a phase of diminishing returns.  This is oversimplified, but what it is meant to illustrate is that we produce the most business value toward the end when most features are implemented and most defects are resolved.

So, our expression, “show me the code” is imprecise.  Not only do you need to “show me the code” as it is now, you need to show me the plan for how to get to “done”, your plan to get it into production, and your commitment to producing peak business value.  I’m not suggesting that we adopt a new expression with this level of verbosity, we just need to collectively make sure that we agree at what “show me the code” is trying to elicit.

Toward Building Value

Our jobs as engineers is to provide value to the businesses that employ us. We are biological machines that are tuned to take complex, abstract, problems and turn them into delivered products and services. The key word being “delivered”.

While there is value in ideas, proofs-of-concept, research, and experimentation, the “proof of the pudding” is in deploying your software to production and then diligently supporting that software until such a time that your time is better spent elsewhere.