DaedTech

Stories about Software

By

Wrapping Up and an E-Book: The Tragedy of the Expert Beginner

It’s been a pretty busy week for me, which is why I haven’t posted in over a week. I’m in the midst of my next Pluralsight course, and I spent the last week getting ready for closing, then actually closing, on a house. On top of that, the Expert Beginner e-book is now available!

ExpertBeginner

Here is the start of the final post in the series and the conclusion of the book:

The real, deeper sadness of the Expert Beginner’s story lurks beneath the surface. The sinking of the Titanic is sharply sad because hubris and carelessness led to a loss of life, but the sinking is also sad in a deeper, more dull and aching way because human nature will cause that same sort of tragedy over and over again. The sharp sadness in the Expert Beginner saga is that careers stagnate, culminating in miserable life events like dead-end jobs or terminations. The dull ache is endlessly mounting deficit between potential and reality, aggregated over organizations, communities and even nations. We live in a world of “ehhh, that’s probably good enough,” or, perhaps more precisely, “if it ain’t broke, don’t fix it.”

There is no shortage of literature on the subject of “work-life balance,” nor of people seeking to split the difference between the stereotypical, ruthless executive with no time for family and the “aim low,” committed family type that pushes a mop instead of following his dream, making it so that his children can follow theirs. The juxtaposition of these archetypes is the stuff that awful romantic dramas starring Katherine Heigl or Jennifer Lopez are made of. But that isn’t what I’m talking about here. One can intellectually stagnate just as easily working eighty-hour weeks or intellectually flourish working twenty-five-hour ones.

I’m talking about the very fabric of Expert Beginnerism as I defined it earlier: a voluntary cessation of meaningful improvement. Call it coasting or plateauing if you like, but it’s the idea that the Expert Beginner opts out of improvement and into permanent resting on one’s (often questionable) laurels. And it’s ubiquitous in our society, in large part because it’s encouraged in subtle ways. To understand what I mean, consider institutions like fraternities and sororities, institutions granting tenure, multi-level marketing outfits, and often corporate politics with a bias toward rewarding loyalty. Besides some form of “newbie hazing,” what do these institutions have in common? Well, the idea that you put in some furious and serious effort up front (pay your dues) to reap the benefits later.

To read the entire conclusion, or if you like this series in general and want to support it, please consider buying the e-book. It is available right now on Amazon and will be available soon in other e-book stores as well. The price in all stores is $4.99. Here it is on the publisher’s site, where you will be able to find links to everywhere that it’s available. (As an aside, any of you with a blog should take a look at Blog Into Book, an 1871 startup that can help you generate an e-book from a book-worthy string of posts on your blog.)

In the interest of full disclosure, I will publish this last post in its entirety around the end of the year. This series of posts is, well, a series of posts, and I certainly don’t want to penalize regular readers of the blog by withholding content. But the e-book is more than just the posts strung together — it is complete with some additional content, better segues, and a more continuous flow. So I’d encourage you to get it if you want to see my conclusion sooner rather than later or if you’d like to read the series as a single work.

Also, I’d like to thank Amanda Muledy for editing and illustrating the book, as she does with my site.

By

Intro to Unit Testing 7: Overcoming Inertia and Objections

In this series so far, I’ve introduced the concept of unit testing, talked about how to avoid early failures and frustrations, and then dived more in depth into the subject. But now that you’re familiar with the topic and reasonably well versed in it (particularly if you’ve been practicing over the course of this series), I’d like to use that familiarity to discuss why unit testing makes sense in terms that you now better understand. And beyond that, I’d like to discuss how you can use this sense to overcome inertia and even objections that others may have.

The Case for Unit Tests

Alright, so this is the part where I offer you a laundry list, right? This is where I say that unit tests improve code quality, document your code, exercise your API, promote (or at least correlate with) good design, help you break problems into manageable chunks, expose problems earlier when finding them is cheaper, and probably some other things that I’m forgetting right now. And I believe that all of these things are true. But after a number of years of faithfully writing unit tests and practicing test-driven development (TDD), I think that I can offer those as appetizers or footnotes in the face of the real benefit: they allow you to refactor your code without fear or hesitation.

First to Contend With: Inertia

Inertia could probably be categorized as an objection, but I’m going to treat it separately since it manifests in a different way. Objections to doing something are essentially counterarguments to it. They may be lame counterarguments or excellent counterarguments, but either way, they take an active position. Inertia doesn’t. It’s either ambivalence or passive-aggressive resistance. To illustrate the difference, consider the following exchanges:

Alice: We should start trying to get our code under test.
Bob: Unit testing is stupid and a complete waste of time.

versus

Alice: We should start trying to get our code under test.
Bob: Yeah, that’d be nice. We should do that at some point.

The former is a strident (and obtuse) counterargument while the latter is an example of inactivity by inertia. In the second exchange, Bob either thinks unit testing is a good idea — but just not now — or he’s blowing sunshine at Alice while subtly saying, “not now,” so that she’ll leave him alone and stop stumping for change (i.e. the passive-aggressive approach).

In either case, the best way to overcome inertia is to counteract it with activity of your own. Inertia is the byproduct of the developer (and human in general) tendency to get stuck in a rut of doing the comfortable and familiar, so overcoming it within your group is usually just a matter of creating a new rut for them. This isn’t necessarily an easy thing to do. You’ll have to write the tests, make sure they stay up to date, demonstrate the benefits to anyone who will listen, and probably spend some time teaching others how to do it. But if you persevere and your only obstacle is inertia, sooner or later test writing will become the new normal and you’ll get there.

Red Herrings and Stupid Objections

RedHerring

Around a year ago, I blogged about a guy who made a silly claim that he wrote a lot of unit tests but didn’t check them in. The reasoning behind this, as detailed in the post, was completely fatuous. But that’s to be expected since the purpose of this claim wasn’t to explain a calculated approach but rather to cover a lack of knowledge — the knowledge of how to write unit tests.

This sort of posturing is the province of threatened Expert Beginners. It’s the kind of thing that happens when the guy in charge understands that unit testing is widely considered to be table stakes for software development professionalism but has no idea how it works. As such, he believes that he has to come up with a rationale for why he’s never bothered to learn how to do it, but he’s handicapped in inventing an explanation that makes sense by virtue of the fact that he has no idea what he’s talking about. This results in statements like the following:

  • Unit tests prevent you from adapting to new requirements.
  • Testing takes too much time.
  • It wouldn’t work with our style of writing code.
  • You’re not going to catch every bug, so why bother?
  • Writing all of your tests before writing any code is dumb.
  • Management/customers wouldn’t like it and wouldn’t want to pay for it.

I obviously can’t cover all such possible statements, but use the smell test. If it sounds incredible or stupid, it probably is, and you’re likely dealing with someone who is interested in preserving his alpha status more than creating good work product. To be frank, if you’re in an environment like that, you’re probably best off practicing your craft on the sly. You can write tests and keep quiet about it or even keep them in your own personal source control (I have done both at times in my career when in this situation) to prevent people from impeding your own career development. But the best longer term strategy is to keep your eyes and ears open for other projects to work on where you have more latitude to set policies. Do an open source project in your spare time, grab an opportunity to develop a one-off tool for your group, or maybe even consider looking for a job at an organization a little more up to speed with current software development practices. You can stay and fight the good fight, but I don’t recommend it in the long run. It’ll wear you down, and you’re unlikely to win many arguments with people that don’t let a lack of knowledge stop them from claiming expertise on a subject.

I Don’t Know How to Unit Test

With inertia and silliness set aside, let’s move on to legitimate objections to the practice. At first blush, you may be inclined to scoff at the objection, “I don’t understand it,” particularly in an industry often dominated by people unwilling to concede that their knowledge is lacking in the slightest bit in any way whatsoever. But don’t scoff — this is a perfectly reasonable objection. It’s hard and often unwise simply to start doing something with professional stakes when you don’t know what you’re doing.

If the people around you admit to not knowing how to do it, this earnest assessment often indicates at least some willingness to learn. This is great news and something you can work with. Start teaching yourself how to do it so that you can help others. Watch Pluralsight videos and show them to your coworkers as well. If your group is amenable to it, you can even set aside some time to practice as a group or to bring in consultants to get you off to a good start. This is an objection that can easily be turned into an asset.

It Doesn’t Work With the Way I Code

I originally specked out this post in the series because of a comment in the very first post, and this section is the one that addresses that comment. Arguments of this form are ones I’ve heard quite frequently over the years, and the particulars of the coding style in question vary, but the common thread is the idea that unit testing creates friction with an established routine. This isn’t the same as “I don’t know how to unit test” because the people who say this generally do know how to write tests — they must or else they wouldn’t know anything about the subject and would make up Expert-Beginner-style stupid excuses. It also isn’t the same as the inertia objection because they’re saying, “I was willing to try, but I find that this impedes me,” rather than, “meh, I dunno, I like my routine.”

My short answer to someone who has this objection is, to put it bluntly, “change the way you code.” Whatever the specifics of your approach, when you’re done, you don’t wind up with a fast-executing safety net of tests that you trust — tests that document your intentions, keep your code flexible, help prevent regressions, and force your design to be easy to use and decoupled. People who code differently than you do, in that they unit test, do wind up with those things. So figure out a way to be one of those people.

On a deeper level, though, I understand this objection because it hits closer to home. I was never the type to bluster like an Expert Beginner, nor am I prone in the slightest to inertia. (I am pretty much the opposite, frequently biting off more than I can chew.) The other objections never really applied to me, but this one did both prior to starting to write tests and prior to adopting TDD as my exclusive approach to developing. You can read that latter perspective from my very early days of blogging. Years ago, I chafed at the prospect of unit testing because spending the extra time took me out of the ‘flow’ of my coding, and I balked at TDD because I thought “why would I start writing unit tests for this code when it might be refactored completely later?” In other words, neither one of these worked with my approach.

But in both cases, I relented eventually and changed the way I coded. I didn’t just one day say, “well, I guess I’ll just start writing code differently from now on.” What happened instead was that I realized that a lot of really bright people and prominent names in the industry had coding and design styles that were compatible with writing tests so it was at least worth trying things their way. It wasn’t a matter of doing something because the cool kids were doing it or resolving to change my ways. Rather, I thought to myself, “I’ll see what all the fuss is about. Then, I’ll either like it or go back to my way of doing things armed with much better arguments as to why my way is better.” So I poured myself into a different way of doing things, forced myself to keep at it even though it was slow and awkward, and, wouldn’t you know it, I eventually came to prefer it.

Convincing people in your group to follow that lead is not going to be easy, but it is doable. The best way to do it is to earn their respect and show them results. If your code is cleaner and freer of bugs and your past projects are easy to adapt and modify, people are going to notice and ask you what your secret is, and you’ll be in a position to show them. It may seem improbable to you now, but you can go from being a person quietly teaching yourself to unit test on the side to one of the key leaders in a software department relatively quickly. You just have to commit yourself to continuous improvement and moving toward proven, effective techniques. Unit testing is just one such technique, but it is a powerful and important one.

By

Go On, Live a Little. Denormalize Your Data

I have years of professional experience with and completed several academic courses about relational databases. This is a pretty familiar topic for me, and I’ve worked with a bunch of them: SQL Server, SQLLite, MySQL, PostgreSQL, Oracle, and even MS Access. I’ve always found them, paradoxically, to be both comfortable and awkward. They’re comfortable because of my familiarity with them and awkward because I’ve used them almost exclusively with OO languages and incurred the impedance mismatch.

While RDBMS are in my comfort zone, NoSQL alternatives are comparably alien but also intriguing. Ayende has made some pretty convincing arguments as to why one should think outside the RDBMS, including a .NET Rocks episode in which he talks about constraints, such as expensive disk space, that applied decades ago when RDBMS were designed and are no longer of concern. I’m receptive, my interest is piqued, and I’ve played a bit with MongoDB To understand how these things work. But I think it really clicked for me the other day when I was staring at a schema that had some definite complexity issues. I think I finally groked the use case for document databases.

I was working with a pre-existing schema recently in which (mildly obfuscated) you have a “customer” who can be part of one or more “programs.” The entities “customer” and “program” each have their own properties and, as any diligent normalizer will tell you, that information should not be repeated. So they get their own tables. Since a customer can participate in multiple programs and multiple customers can be in the same program, this is an “M to N” relationship — represented, predictably, by a linking table. What’s more, customers can participate repeatedly in programs so the linking table will sometimes have multiple participation records per customer-program pair, differing by a participation timestamp. I’m sure those of us who have done any significant database development have played out similar scenarios countless times.

As I wrangled Entity Framework to deal with this and other similar relationships that were making it relatively complicated to pull certain information, I started thinking that this seemed harder than it needed to be. There was no use case for handling “what if the program name or another attribute changes in the middle of its offering,” and there really are no good answers to that question. Right now, the implementation is “you can’t do that,” but this is hardly satisfying. To administrative users, it seems arbitrary and like a system shortcoming. But the alternative is unpleasant, too — additional complexity to allow “partial programs” in the schema or the code.

I started thinking about normalization and whether it really mattered here. Allowing duplication is a cardinal RDBMS sin, but it sure would make life easier for a lot of use cases. I mean, imagine a scheme where there was just a table of customers, and participation was recorded as you went, with the program information being duplicated in each participation record. The downside is the information duplication, but the upside is that changing programs midstream is trivial and there is less table overhead and complexity to maintain. No M to N relationships and worrying about whether a program is current or replaced by a new one.

And that’s when it hit me. RDBMS are great for maintaining, well, relational information. For instance, if I work at a company, I have a boss, and my boss has many reports. Modeling the manager-line employee relationship is a great fit for a relational database because it’s about modeling relationships, like “manager to reports.” Tree structures of composition tend to be a good fit as well, such as assemblies like cars and other pieces of machinery. Parts consist of sub-parts and so on. These are relationships in the sense that operations like “delete” and “replace” make sense.

But what about the one-and-done concept of a customer participating in a program one day? That isn’t a relationship any more than I form a relationship with a waiter that I tip and then never see again. That’s something that happened once — not an ongoing arrangement. And that’s where things really snapped into focus for me. RDBMS and the normalized model is great for managing relationships but is not necessarily the be-all-end-all for managing extremely transactional data in the sense of event recording.

And while I’m probably not in a position for this project to quickly introduce document databases and stir up the works too much, I am considering modeling what I might do storage-wise after a document database there in SQL Server. Perhaps it’s time to throw caution to the winds and start allowing some information repetition in there for historical modeling. If the experiment fails, I can always normalize it. But if it succeeds, adding document databases to the mix will be a lot easier since I’ll just be learning the syntax of the API as I go rather than the fundamental underlying concepts and use cases.

By

Laughing All The Way to The Bankruptcy

I was in sort of a smart-ass mood the other day, and I found myself thinking of something incredibly random. Do you remember that show or special called “To Catch a Predator” in which Chris Hansen and a crew of people would set up sting operations for sickos that would try to meet up with young girls? I found myself wondering, “if that crew has LinkedIn profiles, what are they getting endorsed for?” Pederast Snaring? Child Impersonation? What awful skills to have, public service notwithstanding. How might one get much better skills there?

Well, one way is simply to make them up. That would probably be effective. I’ve been endorsed for Ruby and Objective C lately, two languages in which I’ve never written a line of code. If my skills for that can get endorsed, presumably my skills for anything can get endorsed, whether or not they exist. If I wanted to be the most interesting man in the world, what skills would I have? I started a list of things I’d like to see in my profile, in no particular order, to make people say “whoa — I want to know that dude’s story!”

  • Extreme Ice Fishing
  • Dexterity
  • Octopus Farming
  • Dark Arts
  • Phrenology
  • Bear Whisperer
  • Inverted Breathing
  • Street Pharmacy
  • Boomerang
  • NFL Quarterbacking
  • 19th Century Russian Classics Author
  • Gonzo Meditation

One could create a pretty bizarre and interesting composite and probably get plenty of endorsements for it. In fact, I might get more endorsements for these things than programming languages I don’t know because amused contacts would probably go out of their way to endorse me for Octopus Farming. And as I contemplated this, it occurred to me. LinkedIn is a joke.

I don’t mean that in the sense of “oh, it’s really gone downhill in quality,” but I mean that it is actually, seriously now a joke. I can’t remember the last time I heard the site mentioned in casual conversation where the conversation wasn’t about how stupid and funny the skill endorsement system is. And that’s really strange, given its history.

As far as social networks go, each one seems to kind of have its niche and feel. Twitter is sort of like a bar, where there’s rapid-fire, disjointed conversations and things often escalate quickly due to out of context remarks. Google+ is like an abstract art museum. There’s a lot to see, but it’s generally from the same few people, and the place is really weird and quiet. Facebook is like going to a children’s playground. People you don’t know very well bore you with pictures and stories of their children, and the whole world is watching, so nothing happens that isn’t completely vanilla and boring. LinkedIn’s niche has historically been to serve as office space that hosts professional conferences or associations. People meet up there to exchange contact info and have professional conversations.

But that’s all changed more recently with the asinine endorsements and the uptick in punishing recruiter spam. Now it’s like a professional conference brought to you by Amway and Satan where reality shows like “America’s Dumbest Celebrities marry America’s Fattest Ex-Ball Players” stream constantly. If you want to show up and talk about your craft, you have to hear about a super business idea for cleaning products and watch a few short episodes of utter crap before you get down to business. It feels like you’re at the midway point on a journey from professional conference to brothel, where there are just enough booth babes to make everyone uncomfortable.

Amway

So the joke must be on LinkedIn, right? They haven’t figured out just how stupid the world thinks the endorsement system is, and they’ll probably be horrified when they do? Nope. They know it, and they’re laughing all the way to the bank, because here’s how it works. Recruiters can sign up for LinkedIn to recruit people for jobs, and they pay LinkedIn for this privilege in terms of the amount of people they contact and the amount of responses they receive to their overtures. So LinkedIn is incentivized to ensure the highest volume of contact between recruiters and users of their site, and what better way to do that than a system of ‘endorsement’ that is completely trumped up and phony? LinkedIn has all the motivation in the world to create a system where every person is endorsed for every skill and every recruiter emails everyone.

So while we laugh at their joke of an endorsement system and bemoan the fact that we get endless contact requests and junk mail through their site from recruiters, they’re raking it in. And people tend to give in to the sunk cost mentality of not quitting something that they’ve spent a good bit of time over the years building up. People aren’t likely to abandon all of their contacts. But here’s the trouble, strategically. People aren’t going to rage-quit LinkedIn, but their perception of it will alter as it careens toward internet brothel. They’ll stop viewing it as the professional social network and start viewing it as a spam conduit, and they’ll just stay away. Every time they get an email that Judy has endorsed them for “Time Management” and “Multi-Tasking,” they’ll just say, “ugh” and inch ever closer to creating a filter rule in their inbox to send LinkedIn emails to their junk folders. They’ll just quietly stop coming back.

And over the course of time, Linked-In will cease to be a social network. It will instead become a stream of information from LinkedIn’s recruiters (their customers) to the rest of us non-premium users (the product). And then they’ll be no different than Career Builder, Monster, and Dice — with the difference being that those sites never pretended to be anything other than what they are. Perhaps I’m overreacting, but I just get the sense that LinkedIn has jumped the shark. It’s a silly place, and I don’t much care for going there anymore.

By

Prove It

I’m thinking this is going to wind up being a shorter post, and so might some others going forward. Fact of the matter is that I’m burning the candle at both ends a bit lately. I’m under contract for my next Pluralsight course, and I’m also mired in the bureaucratic morass of marching toward a real estate closing, so between that and 55-60-hour work weeks, I’m a little pressed for time. But, that said, we’ll see how it goes.

I was sitting in a meeting today where participants were discussing a recent initiative. (I was, at this point, a relatively passive observer with no horse in the race.) The gist of it was that the initiative was something that would be mildly pleasing to the user base but had some cost associated with it. It was accepted that this would be a bit of a financial loss on the balance sheet but that the ROI would be an eventual bolstering of the brand via goodwill and reputation points, so to speak. The leader of the meeting put a halt to this talk of generalities saying something to the effect of, “okay, so how much is it costing us, how many users are aware of it, and how positive was their response?” The people who had been discussing this got sort of deer-in-headlights. They seemed nonplussed that they were being asked to quantify something like this. I loved the questions, personally. I thought, “yeah, get those metrics, and then we can at least begin modeling scenarios for evaluating if this is worth doing.”

After that meeting, I retreated to my desk, and worked into the evening at the kind of tidying up that I can only seem to get done after business hours when I close the office door. One of the miscellaneous tasks was to come up with material to present tomorrow at the inaugural team lunch and learn — an initiative that I recently started. I don’t have a talk in my back pocket at the moment, so I was weighing options for it and settled on showing a video of a Michael Feathers talk about the synergy between testability and good design. I’ve recently introduced unit testing to the team, and it seems like a good perspective about unit testing beyond some of the more standard rationales. In the early part of the talk, Michael says (paraphrased from memory) that he often annoys developers by telling them that if their design isn’t testable, it’s not a good design. It’s quite a concept — if it can’t be easily verified, it isn’t very good.

Earlier this evening, I was relaxing and working my way through The Clean Coder by Uncle Bob Martin. In it, Bob cites something that Kent Beck told him about arguing — if an argument goes on for more than five minutes or so, then it’s really a religious war. If arguments are being based on facts, data, and empirical evidence, they’re settled pretty quickly. Rather than continuing to argue and get angry, both sides should regroup, do some research, and revisit the issue later. You can’t make a persuasive case for something without raw, hard data.

This struck me as interesting. Within the span of half a day, I was exposed to three separate events with a very fundamental and powerful underlying theme: “prove it.” If it can’t be proved, what good is it? As the characters in the Game of Thrones books seem to like to say, “words are wind.” Don’t tell me that users like it so it’s worth doing; show me evidence of that. Don’t tell me that your design is great; show me that it works for the required inputs. Don’t argue with bluster; show me that you’re right in such excruciating detail that there is simply no argument.

I don’t think anybody would find what I’m saying here controversial — proving and demonstrating are obviously better than simply claiming things without support. But I think the challenge for all of us is to prove (or at least to attempt to prove) things that we wouldn’t necessarily think of proving. How do you prove that user goodwill justifies spending X dollars? I don’t know, but it’s an interesting challenge. And beyond being an interesting challenge, it’s the kind of question that being able to answer will set you apart from the people you work with and make you in high demand. Do everything that you do in your professional life operating under the assumption that someone will audit your thought process and demand, on the spot, to know why you decided to do what you did. Why did you spend a day changing all methods in the code base from Pascal to camel case? Can you justify what that cost your group in terms of labor? How would you make the case for that?

I’m not suggesting that we should all operate constantly as if there were some insane, whip-cracking micromanager monitoring our every movement. What I am saying is that you can stand out by constantly and easily demonstrating the value and sense in the decisions that you make and the actions that you decide to take. Be that guy or gal. It’s less common than you think.