I just finished reading an excellent programming book. And I emphasize on the word programming. This is NOT a codebook. I think a lot of developers out there get into a viscous cycle of reading, breathing, and sleeping code code code.
And while coding is an important expect of our lives. The coding part is the actual tools in our jobs. It’s treated as a hammer to a carpenter. Knowing how to use our coding talents and when to use it is as important of the act of using it. And this philosophy of thinking is why it’s so imperative that I strive to read books that are not just coding books but programming philosophy books.
The best thing about programming philosophy books is that they very rarely get outdated unlike coding books that are almost outdated by the time you get your hands on it. The book I just finished reading is Programming Beyond Practices: Be More Than Just a Code Monkey.
The book is broken up into 8 chapters that highlight different stories similar to what you would typically face as a software or web developer. You’ll learn how the people in these stories approach the different scenarios and learn invaluable insight on their failures and their successes.
Here are some big take always for me while I was reading this book.
“Figuring out the right balance of when to play fast and loose and when to tighten things up takes practice…” p14
This is to me is one of the most important development and business skill one can attain. Many of us don’t live in an ideal world, so compromise is something we deal with several times during a project. Knowing when to create technical debt or when to say enough-is-enough and communicate that technical debts needs to be paid down before new features can be added is a skill and an art.
“Adding the new sidebar won’t require modifying any existing behavior except for the UI for viewing wiki pages. In theory, this seems to be a low-risk change. In practice, you know there’s no such thing.” p24
In the book, the client wanted a new feature, which involves add a sidebar that allows for easy navigation to other past wiki pages. Basically a top 10 list containing links to the most recently published wiki pages. It sounds simple enough. The moral of this story is that things aren’t always as they seem. And although this particular feature in itself only involves a simple database query and some styling modifications, the story outlines how things can turn out to be an iceberg with problems hidden beneath the surface. In this story, the two example issues ranged from mild to severe.
The mild issue was manageable; it was tweaking and fixing long wiki titles that messed up the layout when viewed in a narrow mobile device. This issues is just a tweak in the stylesheet and some additional mobile testing. Seasoned developers may already have predicted this issue and have built workflows to prevent such issues. In addition, this issue is easily to diagnose and the issue is directly related to the new feature.
However, there are more severe issues that can arrive they are not as predictable or easily foreseen. In the story, the severe issue was having bad wiki pages showing up in the sidebar. After further investigation, the bad wiki pages are introduced into the database from a bug in the auto-saving functionality. This bug is not directly tied to the new functionality. Unfortunately, because the new functionality (add a sidebar of 10 recently published wiki pages) now brings an unrelated bug to the surface, resolving the unrelated bug is now a criteria in order to deploy this new feature. Resolving this bug requires scrubbing the database of the bad wiki pages and fixing the auto-saving functionality. (Assuming we can’t query the database another way or creating technical debt.) This is a why communication and early detection is key. This is also why developers should set reasonable expectations and time-estimates so that issues like this can be resolved without dramatically affecting timelines.
“Maybe there’s no such thing as a purely internal concern. Maybe as long as our code talks to and interacts with the outside world, there will always be potential for customer impact when things aren’t working as expected. If we pay more attention to what is happening at the boundaries of our system, and treat any issue that happens there as one worthy of careful attention, we’d probably get a better result.” p41
Let me provide some context to this quote. In the story, the developers were getting email alerts that turned out to be triggered by a web crawler. It was nothing disastrous such as the site going down, the number of emails although plenty was nothing close to what one would experience if it was a spam attack. In the beginning, the developers speculated that the reason why they were getting the alert emails was the unorthodox way the web crawler was spidering the site. It’s was not something end-users can do. So they just blocked the IP and left it at that.
Well this happened two more times over the course of a few months and it became embarrassing on the third time it happened. On the third incident, the bot did create massive amount of spam. The amount of emails was large enough to raise their send limit above their account threshold causing the account to be halted by their email delivery service. This caused the site to be unable to delivery any emails. A total disaster. When this occurred, the issue was soon thoroughly investigated and a small fix was applied. While investigating the issue, the developers noticed (if it wasn’t already obvious) that the error reporting emails were using the same email service / coding with the user notification emails. A bad design for this particular website.
Originally, the issue was just a mere annoyance in that the developer’s inbox was getting filled with a lot of unhelpful cryptic email alerts. The simple “solution” was to block the IP address of the web crawler causing the issue. They analyze the cryptic email and deemed that the bot was doing something a real human would never do. So blocking the IP was fine enough and left it at that since it was affecting end users.
However, by not dealing with the issue and taking it seriously, the developers didn’t identifying that the error alerts were using the same email system and service as the end user email notifications system. Having the two systems using the same premium email mailing service was a bad design for this particular project. Finding this out was a catalyst after deciding to investigate further and fixing what was causing the alert emails.
So the moral of the story, small issues sometimes mask bigger issues. Even if the small issue is only internal, and not “important,” sometimes these issues are hiding public facing functionality. It’s often quite easy, especially during times when developers are overflowed with work to blow-off small “internal” or annoyance issues and not take the time to thoroughly understand what the issue is and explore if it’s a symptom of bigger problems.
“Be cautious when depending on an external service for something other than what it is well known for. If you can’t find many examples of others successfully using a service to solve similar problems to the ones you have, it is a sign that it may be at best unproven and at worst unsuitable for your needs.” p42.
Self-explanatory. But it can be hard to execute in real life. I’ve seen teams get stuck with using a service provider or a technology because the excuse is, hey why not use XYZ for that too? I mean, we’re already paying for it or we already have code for it and with a little creative programming we can make it work for that too. This can be dangerous thinking. Just because a service or software library CAN do it, doesn’t mean it should do it. If it’s not a supported feature or you’re really wrangling the code to do something it’s not intended to do, you may run into some gnarly unexplainable bugs and wonder why you can’t find other people on the internet running into the same issues. In addition, vendors can drop unsupported features at a moment’s notice leaving you scrambling to find another solution.
A scenario that hits close to home is just because Azure “supports” PHP. I think they go as far to say that officially. This doesn’t mean you take them on their offer. I assume the majority of people using Azure is to host Microsoft products and technologies. That’s what their bread and butter is and what their known for. It’s like when I go to Five Guys. Yes they sell hotdogs, but who goes to Five Guys to buy hotdogs?
“Real problem solving is often a solitary experience. You can get support from others, but in the end, you need to understand all the pieces of a problem for yourself in order to see how it all comes together. That’s the essence of what it means to think rigorously anyway: to understand something with a great deal of precision and detail.” p56
I thought this was an interesting quote pull from the book. It’s something to ponder upon when asking another developer for help.
“Remember that unshipped code is not an asset; it’s perishable inventory with a cost of carry. Help everyone involved in your projects understand this by focusing on what valuable work gets shipped in a given time period, rather than trying to make sure each person on the team stays busy.” p106
It’s easy to get caught up with not releasing a project until the code is just “perfect” or the website as a whole is 100% bug free. Or signing off with a plan to launch with every single bells-and-whistle feature rather than a high probability of early/on-time launches containing just core-pillar functionality. This is obviously more complex in the real world with so many variables. Teams and leaders must consider what’s more important; launching with a huge bang but it’s late and lost market share to a competitor or launching early to gain market share but with a no-frills and bare-bone functionality? The last part of the quote is important ton consider as well. By balancing towards core-pillar functionality for product launches, every piece of the pie divided among the developers is equally important. Everyone would be working on pillars and not bell-and-whistles that may be super challenging and time consuming with a high risk of delaying the project and is not mandatory for launches.