Search This Blog

People Tend to Do What They Know, So Learn What You Don't

People will do what they know. It's inescapable. When the spotlight is on, and you are expected to perform, most people are going to go with a tried and true response, not an untested experiment with unknown risks. In the context of engineering, people will tend to use designs, architectures, and tools that they've used before. It's entirely natural and rational, and in most cases going with a known design will yield predictable results. But that is not always the case.

Sometimes adhering to what you know can lead to some prickly design traps. Probably the worst of these is NIH (not invented here) syndrome. In its strongest form, this disease presents itself as a team's complete inability to accept design components or subsystems from anyone else, even within the same company. Everything must be designed and implemented in-house from the ground up. In weaker forms the team may use some standard libraries and frameworks, but the default state of their design process is still roll-your-own. NIH normally becomes a problem only if the entire design team is afflicted. If a minority of designers have this tendency, they can usually be overruled or have the impact of their decisions minimized. But if company culture is saturated with this mindset, teams will have an awful lot of work to do.

Another design trap born of only doing what you know is forcing a solution to fit the problem. If the design warrants a solution that doesn't exist in your repertoire, and you don't take the time to properly understand the problem and research its design space, you may end up trying to use a design that is ill-suited to the problem or solves an entirely different problem. This is the classic case of trying to fit a square peg into a round hole. It can't be done without significantly distorting the peg or the hole or both, and the result ain't gonna be pretty.

Possibly the most common trap is plain old suboptimal design. You may know a decent solution that fits the problem, but a better one exists that makes the design more elegant or more efficient or more flexible. The better solution could be an algorithm, architecture, or framework that you put off learning or are not yet aware of. You end up using the suboptimal design because it's what you know, and it can happen at any level of design.

All of these traps have something in common. They can be disarmed with the will to learn what you don't know. If you adhere to only those concepts you already know, it is easy to fall into one or more of these traps, but if you are determined to research the problem at hand, deepen your knowledge of the application domain, or experiment with new tools on the side, you can overcome the pitfalls and make better design decisions.

Let's examine each of the traps listed above in reverse. To avoid suboptimal design, the simplest thing you can do is take a look at what others have already done to solve the problem you're working on. It is almost a certainty that someone else has already run into the same problem, solved it, and published the solution for others to use.  It's almost as likely that multiple solutions are out there for you to choose from, if you use some creativity.

Leonardo da Vinci invented armored vehicles, helicopters, and hang gliders in the 15th century, long before engineers built functional versions of them. He worked out a lot of the main design problems before the materials and manufacturing processes even existed to make his inventions a reality. If he could do that centuries ahead of time, it's probably safe to assume that almost all problems have already been solved in some context. Most innovation today is the refinement of those solutions or the application of those solutions to new fields. Your problem is probably not so unique that nobody has come across it, yet. Spend a little time looking around before diving into a solution that may be suboptimal.

Forcing solutions to fit the problem can be thought of as a more extreme case of suboptimal design. To avoid this pitfall, try learning more about the problem domain first. The more you know about a domain, the more you come to appreciate its subtleties and nuances, and the more likely you will realize how it is different from things you have done in the past.

For example, on the surface, system modeling and real-time signal analysis seem to have a lot in common. They utilize many of the same DSP concepts, but the details are what set them apart. In a real-time system, a lot of effort is put into streamlining calculations with multiple stages of computation separated by memory buffers to relax timing constraints. In contrast, a system model is attempting to accurately model a real system on different hardware while making simplifying assumptions to speed up the execution of the model. Even though they may be performing the same calculations, the different constraints of the two problem domains will make the solutions' architectures drastically different. Even within each of those domains, the constraints of the specific problem being solved is important, and slight changes to the requirements can have a ripple effect on the rest of the system. Learn more about the problem domain to avoid the misapplication of an old solution to a new and different problem.

And now we arrive back at NIH syndrome. Things get more complex here because simply learning more about the application domain or researching solutions to the problem at hand will not dissuade someone from writing their own solution. There is a certain comfort and familiarity in writing your own code that is difficult to overcome. You know the code inside out because you wrote it. You can debug it and fix it if there are problems. And let's face it, your code is a gold-plated work of art while every other programmer's code is crap, right?

Let's discuss this a little in the context of an example from the video game industry. When embarking on a new game design, one of the basic choices that needs to be made is whether to license a game engine or build your own. If you build your own, you own it for better or worse. It's your own code, and you have total control of it and full knowledge of how it works. But you have to start at square one and it's going to take time to develop. If instead you license an existing game engine, you can start with known working code that hopefully comes close to your needs. You have to pay for it, but having a working engine can be a huge asset. And depending on the support you can get, you could have a robust platform with critical help for developing your game.

So how do you choose? Well, even if you license the engine, you're probably going to be changing it quite a bit and writing lots of code. You're going to learn a lot about that engine by the time you're done. Then on the next game project, it will be something you already know - another tool in your programming toolbox. If it was acquired with less time and effort than a home-built engine, that's a big win. If it came from a blockbuster game, it's already been tested and proven in the wild, another big win.

I'm not saying that licensing game engines is always the way to go. Sometimes existing engines don't fit the requirements or they're too expensive. The details of each project are important. The point is that the decision should be made using careful analysis of the project's requirements and constraints, not dictated by a team suffering from NIH syndrome. Knowledge of multiple game engines helps tremendously in that decision. The same is true for any software project when deciding whether to write your own code or use existing libraries and frameworks. The deeper your knowledge about what's already out there, and I mean functional knowledge that comes from having already used the tools under consideration, the more informed you are in making that decision. Knowledge is power.

Because people tend to do what they know, you need to keep learning what you don't know to make better design choices. The pursuit of knowledge is never-ending. Get comfortable with that. Every tool you can add to your programmer's toolbox is an asset that you may find useful at any time, and you want to keep freshening and maintaining your toolbox, lest you be caught by a problem for which you have no ready solution. And the best tools in your toolbox? An inquisitive mind and a will to learn.