Monday, September 1, 2014

Oyster Books Review

I thought I'd share my experience trying out Oyster Books - an online e-book subscription service that offers unlimited e-book reading for $9.95 per month (think Netflix but with books). Over the coming months, I plan to try all the major services (Oyster, Scribd, Entitle and Kindle Unlimited) and blog about them.

Sign-Up

Signing up was a breeze and comes with a one month free trial, a $9.95 value. For an even better deal, you can get $15 in credit if you sign up with my Oyster invitation.

I signed up using the Android app but you could just as easily register with the iPhone/iPad or your web browser. It does, however, require a valid major Credit Card so that billing may start at the end of your trial should you choose not to cancel.

Book Selection

The book selection is impressive. A lot of book subscription services like to tout large numbers, over 500,000 books in Oyster's case. However, the count of books is irrelevant if there's nothing you want to read. I had no problem finding books by well-known authors that I actually wanted to read.

Oyster recently added Simon & Schuster's entire back list (e.g. books older than one year) to its catalog. This really adds to their breadth with authors like Stephen King and Dan Brown. For the curious, you can search for your favorite authors and books to see if they offer it. In a lot cases, I found a healthy, but incomplete, selection of books from my favorite authors such as Dan Simmons and Neil Gaiman.

Reading Experience

My normal reading is done with a Kindle Paper White and I fully expected a degradation in experience with Oyster. With my Paper White, I love the e-ink's lack of glare and the soft glow of the backlit screen. This is especially nice when reading in bed.

At first, I tried reading with Oyster on my Nexus 7 tablet. I found it too heavy, though, compared to my Kindle. I quickly switched to my Samsung S4 and pretty much did all of my reading there. I was able to adjust the font size and background to be night friendly.

Options: Night Mode

Compared to the Kindle Paper White and the Kindle Android app, the Oyster application was frustrating at first. With the Kindle, they've optimized the touch screen for the most common operation: flipping to the next page. As such, the page turns forward by touching all but the very leftmost side of the screen. Not so with Oyster.

Oyster's Android app makes you touch the rightmost side of the screen or use the volume controls to move the page forward. This is especially frustrating if you want to hold the phone with your left hand. For me, the volume controls weren't an option since they made a distracting beeping sound on my S4. I couldn't figure out how to turn the beeping sound off.

The Android app also had some lag to it while re-rendering from portrait to landscape mode or vice-versa. I also had a few frustrating experiences when I got out of bed with the phone only to find that it had reset back to the beginning of the chapter. I suspected this had something to do with changing the phone orientation. I only had this happen one evening but it happened several times and was very frustrating.

As far as other platforms, I did spend one afternoon reading on my Chromebook. It offered all the same options as my phone as far as font customization, etc. It also seemed to synchronize where I left off on my phone seamlessly.

It should be noted that there's no ability to bookmark or take notes, unlike the Kindle. For me, this was a minor loss but I could see how this would be a negative for some people.

Cancellation

Cancellation was even easier than signing up. There's not much to say here except that it is no hassle. You can cancel anytime and then resume later. You don't get any partial refund but do get to keep using the service until your month is over.

Takeaway: This Will Change the Way You Read

Oyster has the ability to change the way you read and I took full advantage of it. I had several books in flight at the same time, which was nice. With the Kindle, I typically read books one at a time since it costs me about $10 for each book.

A good analogy for traditional Kindle vs Subscription books would be as follows: I like steak but if I ate it every day, I'd soon tire of it. I also like seafood. It'd be nice to have steak one night, seafood the next, chicken the night after that and so on. Oyster lets you read like this. It gives you variety. That's really nice.

Also, you don't have to decide whether to drop $10 on a book based upon a Kindle sample that only got you slightly past the introduction. You can read as far as you want to and then pick up something else if you don't like the book. Decide for yourself! Sign up for the free trial or use my invitation for $15 in free credit.

Wednesday, October 31, 2012

When Static Analysis Is Not Enough

Wikimedia Commons under GNU FDL 1.2

We've all had the experience of needing to determine if a particular piece of code is still used. IDE's are fantastic at this type of static analysis. Just because your IDE informs you that a piece of code is referenced, though, doesn't necessarily mean that the code is still used at run time in a production environment.

A simple way to find out if a piece of code is executed is to insert a log statement. However, what do you do when there are multiple entry points to the piece of code and you suspect only some of them are still used? You would really like to know which code paths are exercising the functionality so that you can prune the obsolete references.

A simple and clever way accomplish this is by inserting the following commons logging statement:

When the suspect code is encountered, a log message will result along with a stack trace. The stack trace will let you know the code path used to arrive at the log statement!

Saturday, October 20, 2012

Nobody Knows How to Make a Pencil

Courtesy Julian Colton, Wikimedia Commons

No single person knows how to make an object as simple as the common pencil.

It's true.

Leonard Read is well known for this observation in his economic essay, 'I, Pencil'. In it, he describes the specialized knowledge required to make this deceptively simple looking object.

How to Make a Pencil

At a minimum, you need to know about:

  • Growing Cedar Trees
  • Harvesting Trees
  • Milling Lumber
  • Manufacturing a Tint for the Milled Lumber
  • Mining and Refining Graphite
  • Manufacturing Glue
  • Manufacturing Lacquer
  • Mining and Refining Zinc and Copper into Metal Sheets for the Collar
  • Growing and Refining Castor Beans for the Eraser

Clearly, no single person could possibly know how to make a pencil!

How to Make Software

Consider the field of software development. The typical development project involves working with customers, analysts, managers, software engineers, QA engineers, network engineers, dba's, sys admins, etc.

We each play our part in the process of making software. As in the pencil example, one person simply cannot perform all of these activities with a high degree of skill. We need solid relationships with others in order to accomplish the end goal of releasing high quality software. If we are to succeed, good relationships are imperative.

Lobotomy Victims

Recently, a Pidgin bug ticket made the rounds because it was titled 'SSL Support appears to have been written by a lobotomy victim'. While a lot of people got a good chuckle out of it, it was a demeaning ticket that sought to elevate the author at the expense of somebody who likely dedicated their spare time to the development of the software (it should be noted that the author was chided in the ticket and the title of the ticket has since been revised).

Sadly, it is not uncommon to see this type of behavior within our community. Why do so many of us insist on disparaging others? Why do some insist on elevating themselves at the expense of others instead of collaborating to make us all better engineers? How can we expect to be successful if we alienate others and ruin our relationships with the very people we need to help make our version of a pencil?

Community over Code

There's a notion of 'Community over Code' that a lot of open source projects adhere to. It's not a new notion but it was new to me until I encountered this post recently — it's spot on. The relationship part of what we do is much more important than the technical part.

In short, it's all about community. If we want to succeed, we must value our interpersonal relationships above all else. You can't do this alone. Nobody knows how to make a pencil.

Wednesday, September 12, 2012

How the Bystander Effect is Ruining Your Code

Source: Abu Badali, CC 2.5, via wikimedia

In 1964, for thirty-five long minutes, thirty-eight citizens of a respectable Queens neighborhood watched as a twenty-eight year old woman named Kitty Genovese was brutally raped and murdered. Not one person phoned for help.

The Bystander Effect

This story illustrates an unfortunate property of 'The Bystander Effect': The probability that somebody will render assistance decreases as the number of people increases.

As software engineers, we see the bystander effect in action every day. If your codebase is of any reasonable size and age, you are likely to have problems such as lack of encapsulation/separation of concerns, complex (or just plain wrong) class hierarchies, methods that are so long that they read like a chapter in the latest Stephen King novel, untested code, broken tests — and nobody does anything about it.

Causes

The root of the issue is lack of ownership. We assume that somebody else will fix the problem. In the case of our codebase, we may be apathetic because "it's not my mess". That's the problem with us software engineers: we don't want to fix problems caused by other engineers. The attitude of "it's not my mess" prevails.

Oh, but is it ever your mess.

Negative Externalities

Economists speak of something called 'Externalities'. That's a fancy way of saying that person A gets the benefits of something and person B pays for some or all of the cost. As person B, you will eventually need to modify that horrible class that person A wrote. You'll wish it were better designed. You'll wish you had functioning tests. You'll end up doing more work just to make a simple change. Your boss will wonder why you can't perform a simple task in a timely manner. You pay the cost for somebody else's poor decisions — that's a negative externality.

A Culture of Ownership

Fixing the side-effects of negative externalities is simple: take ownership of the problem — whether you caused it or not. Who cares about who is responsible? Those people are likely long gone anyway. Still waiting for them to fix it? It's not going to happen. Assume that nobody except for you is going to make things better.

Once you do that, a culture of ownership starts to emerge. When those tests that you worked so hard to fix end up breaking, you're on top of whomever broke it because you have sweat equity.

Likewise, you start to get improvements in your codebase 'for free'. You open up a piece of code that previously had issues. You dread working inside of it. Your sense of dread soon turns to delight as you find that some kind soul has made the world a better place. All of this happens because somebody else felt a sense of responsibility. That's a wonderful thing.

Act! Now!

So how about it? Spend a day this upcoming week in a section of code that is like taking a tour of the wrong side of town. Commit a random act of coding and leave a comment:

/* 
JKH 09/12/2012 - Refactored poorly managed transactions. 
If this makes you happy, PAY IT FORWARD!
*/

Tuesday, August 21, 2012

Five Fatal Logical Fallacies of Software Development

Source:Carlos Botelho, CC3.0, via wikimedia

Fallacy Fallacy

Drawing the conclusion that another engineer's point is incorrect because he cannot adequately defend his position.

Don't immediately disregard somebody's opinion due to poor argument construction. We often have an intuition about engineering solutions — an intuition that isn't always easily quantifiable into a well formed argument. You should seek first to understand the possible reasons for taking an opposing position so that, ultimately, your designs will be better informed. Moreover, if you are in a decision making position, your decisions will be viewed as more fair and well thought out.

Appeal to Tradition

Justifying or defending a coding practice by citing precedent.

I encounter this argument all the time when introducing new software into existing systems. It is usually an internal struggle between introducing newer, more well thought out designs vs adopting a 'When in Rome do as the Romans do' strategy to maintain consistency in the code base.

Processes, procedures and coding practices aren't developed in a vacuum. There are a dizzying array of external factors that influence these decisions. Many times, if you examine the factors that led to these decisions, you'll find that the original reasons no longer apply or are diminished. It never hurts to apply the five whys to find out if it makes sense to continue a particular practice.

The Sunk Cost Fallacy

Believing that you must continue forward with a particular design, project, etc. because you've already poured too much time, money and other resources into a solution.

Software engineering is hard. We never have all of the facts when we start a project. We should not be afraid to change direction once new information leads us to question the viability of our original decisions.

Is that refactoring effort that you thought would take 2 days instead proving to drag into 2 weeks with no end in sight? Don't be afraid to stop because you now know that its more involved that you originally thought. Cut your losses. Your project deadline and your stakeholders will thank you for it.

The False Dichotomy

Constraining a problem space to two — and only two solutions.

I encounter this most often when troubleshooting production issues that aren't yet well understood. Statements like the following are often made: 'The slow performance is due to either a missing database index or a changed execution plan from crossing a partition'.

While these may be likely culprits, such statements ignore an entire universe of other possibilities including JVM GC pauses, network latencies, etc. Rarely are there only two possibilities when dealing with undiagnosed problems.

Confusing Correlation and Causation

Assuming that because events occur together that one must cause the other.

This is another fallacy that tends to be seen when troubleshooting production issues. In such situations, reams of data are analyzed and we humans do what we're best at: pattern recognition. If we're not careful, this pattern recognition can lead us to assume that one event causes another to occur.

Incorrectly asserting causation is dangerous in this case because it can lead us down unproductive exploratory paths and thus lead to longer diagnosis times. Knowing in advance that events are correlated but not necessarily causal can introduce a healthy dose of skepticism into the troubleshooting process.

Wednesday, August 15, 2012

Agile Processes Feed Paris

Source: Benh Lieu Song, CC3.0, via wikimedia

What do traditional top-down project management approaches have to do with moleskin pelts and how are agile processes involved with making sure that the city of Paris doesn't go hungry? Let me explain.

Rotting Moleskin Pelts


Thomas Sowell, in his book Basic Economics: A Common Sense Guide to the Economy, provides an excellent example of what happens when you try to micromanage the coordination of activities from the top down. Specifically, he cites an instance where the Soviet government decides to raise the price it pays for moleskin pelts. Markets being what they are, more pelts are provided since they now fetch a higher price.

Here's the rub: industry had no use for the pelts. They rotted in warehouses. The government was aware of the issue but didn't have time to deal with the matter. Sowell notes:

"Its [the government] members are too busy to decide. They have no time: besides setting prices on these pelts, they have to keep track of another 24 million prices"
Trying to decide the appropriate price for each item for sale and allocate resources to the appropriate centers of population turned out to be a futile task. Centralized planning is not efficient.

Who Feeds Paris?


Who feeds Paris? That's the question Charles Wheelan poses in his book Naked Economics: Undressing the Dismal Science. How is it that nearly the right amounts of bread, fish, meat, coffee, etc are available for purchase on a daily basis? The answer is simple: the individual participants in the market decide the correct quantities. The system works quite well.

To prove this, let us take the example of a restaurant that sells steak to its patrons. Assume that the manager over-estimated his patron's appetite for beef. As such, the beef rotted and his profits were diminished. Next time, he orders less beef from the butcher. The butcher in turn orders fewer cattle from the farmer. If the trend persists, the farmer orders less feed since he needs to raise fewer cattle.

The amazing thing about this example is that no singular participant coordinated these activities. It happened 'all on its own'. This type of activity plays out daily on a massive scale in our economy. It is breathtakingly efficient.

Parallels to Agile


Traditional project management approaches have a lot in common with the rotting pelts story. These approaches are often misapplied and end up being micromanaged by a singular project manager. This person is usually completely frazzled because the task set before them is impossible to perform well. A few people cannot possibly coordinate the daily activities of all of the participants in a semi-complex project. The story about the pelts illustrates the futility of such an exercise.

Agile processes address this coordination problem by setting the individual participants free to work out the details between themselves. This enables management to focus on strategic direction (e.g. future projects for the teams). Further, it enables the leadership to realize the goal of becoming a service role. Leaders are empowered to support the teams by assisting in the removal of obstacles, etc instead of spending their time coordinating efforts between individuals.

The software engineering profession has been moving in this direction for years due to one simple reason: it works. Why is it, then, that the companies of the prototypical free market economy of the world insist on running their businesses like the centrally planned economy of socialist Soviet Russia? 

Indeed, some organizations are starting to adopt agile processes to manage non-technical projects. National Public Radio is a shining example of this. However, the vast majority of companies continue to do what they've always done, somehow hoping that this time it will be different. These companies will be vanquished by their more agile competitors. History shows this time and again.

Keep this story front of mind when you are about to launch your next project - software or not. Agile processes are the epitome of a free market economy. Free market economies work - it is how Paris gets fed.




Tuesday, August 7, 2012

Is Your Code a Sherman or a Panzer Tank?




Sherman Tank
Sherman Tank (Wikimedia Commons)

The History Channel produced an insightful documentary comparing the American Sherman tank with the German Panzer tank in WWII combat. The lesson that follows is valuable for any professional software engineer.

Sherman vs Panzer


The Panzer was a tank to be feared by the Americans: it was designed to high German engineering standards, had nearly impenetrable front armor and fired a canon with such velocity that it could easily annihilate the Sherman tank. Stacked up next to the Sherman, the Panzer was the clear victor.

The Sherman, though, had one overwhelming advantage that the Panzer did not: ease of production. The United States was able to out-manufacture the Germans by a ratio of 2 Sherman tanks to each Panzer.  This singular advantage turned out to be decisive for the Allies.
The Germans engineered a superior machine at the cost of taking longer to manufacture. This ensured defeat when outnumbered by the more plentiful Allied Sherman tanks.

Implications for Software Development


What does this have to do with software development? Ask yourself: How much time am I spending engineering the perfect piece of code? I bet it is too much.  If you aren't careful, the increased time to market will allow a competitor to manufacture a Sherman that will make you irrelevant in your market.

This isn't an argument for sloppy design. We should follow best practices like coding to interfaces, using abstractions sparingly, separation of concerns, etc. There's a point, though, where your design is good enough and time to market is more valuable than a technically superior piece of code that is late due to over-engineering.

So I ask, is your code more like a Sherman or is it more like a Panzer tank?