Tuesday, August 24

Checks and Balances: Don't trust yourself

I consider myself to be a pretty smart guy. Perhaps that's a little conceited. But, one of the reasons I consider myself to be so smart is that I don't trust myself to always make the best decisions. Whenever I have to make an important decision, and I have the luxury of time, I bounce it off my right hand man. More often than not, he's eager and willing to disagree with me. Debating the issue with him sometimes opens my eyes to a point of view I might not have considered. I didn’t hire him to be my lackey; I hired him to compliment my skill set.

My second in command reminds me of myself a decade ago; excited about new techniques and technologies and anxious to apply them. I, however, have become the old codger I used to despise; always choosing the safe and established route and thinking very long term about decisions, trying to see the big picture. How boring I have become. But I have much greater responsibilities now. The success of my company and its products depend on me making the right choices.

I love being the man in charge. I thrive on the responsibility, and I’m confident in myself to make the right choices. However, I’m modest enough to realize that I don’t know everything. Listening to somebody that disagrees with me helps me to make a better informed decision. I don’t become defensive; I become a sponge. I soak it up. It’s not my goal to change the other person’s mind, so arguing with them is futile. My goal is to succeed, so I listen and consider their comments.

A prime example of my mentality is this very blog. I don't post these rants because I think I know everything and I think I’m doing you a favor by sharing my wealth of wisdom. I post my ideas and opinions here with the hope that somebody will disagree with me. Not only disagree, but make an intelligent rebuttal. Open my eyes. Show me the error of my ways. Prove me wrong.

Are you up for the challenge? If so, read my last few posts and speak your mind. I'm dying to hear your opinion. Enlighten me!

7 comments:

Anonymous said...

You're in charge of a software group but you:

1) Until recently were using MS J++ for software development (i.e. circa 1997 technology)?

2) Eschew any of the collections from version 1.2+ (i.e. circa 1999 technology)? What's wrong with a vector or a hashtable? *shrugs*

3) Don't understand the need for exception chaining?

Having spent the last 3 years managing the engineering department for a large insurance company, I can honestly say that you are WAY behind the curve in regards to being anything close to a technical lead for a group of software engineers. How can you provide technical vision for a team when you yourself are wallowing in 7 year old technology?

"I'm confident in myself to make the right choices". I remember reading a quote that said something along the lines that incompetent programmers think they are competent. Perhaps that applies here.

Teflon Ted said...
This comment has been removed by a blog administrator.
Teflon Ted said...

Well, I was hoping for some intellectual repartee, but if all I can troll up is some flame bait, I'll work with it.

"Until recently were using MS J++ for software development (i.e. circa 1997 technology)?"--
The project was conceived "circa 1997" and at the time that technology was considered "bleeding edge". Fast forward to today. It all still works. It's stable. It's fast. It's secure. It's been running for years without fault. Why change it?

"Eschew any of the collections from version 1.2+ (i.e. circa 1999 technology)?"--
Yes. If you read my post, you know my reasoning. If you disagree, explain yourself.

"What's wrong with a vector or a hashtable?"--
Nothing; that's why we still use them.

"Don't understand the need for exception chaining?"--
Do you? Enlighten me. Make a point. Any point.

"I can honestly say that you are WAY behind the curve in regards to being anything close to a technical lead for a group of software engineers."--
Why? Give me a reason.

"How can you provide technical vision for a team when you yourself are wallowing in 7 year old technology?"--
Restating my points above, sticking with a solution that is stable, fast, secure, and has remained so for many year, is not "wallowing" by any stretch of the imagination.

"I remember reading a quote that said something along the lines that incompetent programmers think they are competent. Perhaps that applies here."--
A humorous jab, but completely uncalled for.

Anonymous said...

Ok, Intellectual repartee...

Well, maybe. Since I don't know what product you make/sell, it's hard for me to comment on why you are still using 1.1 technology or why you are still actively developing a 7 year old codebase.

I was being tongue in cheek when I mentioned vectors and hashtables--I should have surrounded the comment with quotes since I was paraphrasing your earlier blog. Limiting yourself to these two basic datastructures is like trying to work on your car with a hammer and a screwdriver. The variety of collection types available in 1.2+ and the superinterfaces allows you alot more flexibility in architecture. For example, you can pass a List around without the client needing any information about what TYPE of list it is. If you later decide that the access patterns have changed and need to swap out an array based list with a linked list, no client code needs to change if it has been written to be agnostic as to the type. Your only other recourse is to roll your own collections, which may be an interesting excercise for an undergrad CS student but is a waste of time in a production system when high quality implementations are already available.

While modern JVM's reduce the cost of synchronization, it is still a performance bottleneck for heavily used containers that don't require multi-threaded access. If your application is 'fast enough', perhaps you don't heavily use your containers but why would you want an artificial governer on your collections anyway? It's ironic that you quote the 'premature optimization' quote when that's exactly what the Java developers did when they made the methods on the 1.1 collections synchronized.

Regarding Exception chaining: You talk about losing the context of the original exception but that's exactly what chaining prevents. I've seen too much code where an exception is caught and rethrown as another exception with new Exception (e.getMessage()). This loses the original exception context and makes finding bugs VERY difficult. Exception chaining allows you to better implement patterns such as facades and delegates. For instance, if I create a DataReader interface that has an initial implementation that reads from a file, should I throw an IOException to the client? What if I later decide to put my data in a database and now the code throws a SQLException? Throwing these low level exceptions to client code is fraught with problems, the least of which is expecting the client to know what to do with them. It's much easier and safer to wrap the low level exception into a higher level exception that the client can deal with. This prevents you from having to rewrite your client everytime you change the underlying implementation. For instance, why not have a read method in my fictitious DataReader throw a ReadException? Now, I can wrap this exception around the low level exception. The client knows how to deal with a ReadException without needing to know how the data is being read and by wrapping I maintain the original stack trace for debugging. Having had to refactor quite a few systems that threw SQLException to the client, among other things, I can tell you from first hand experience what a poor and unmaintainable idea this is.

Teflon Ted said...

Thank you! Excellent points. I'm dubious that this is the same "Anonymous" that authored the first post [this follow-up is quite well articulated in comparison] but I'll give you the benefit of the doubt.

"Limiting yourself to these two basic datastructures is like trying to work on your car with a hammer and a screwdriver."--
I love analogies, and that's a good one.

"you can pass a List around without the client needing any information about what TYPE of list it is. If you later decide that the access patterns have changed and need to swap out an array based list with a linked list, no client code needs to change if it has been written to be agnostic as to the type"--
Actually, I have a rule within my team against passing around generic collections because this has bitten us in the arse before. We changed the type of object contained in a collection that was passed in and out of other objects and it broke way on down the line when an older piece of code expected the former type of containee. We wasted a lot of time tracking down the problem. I realize that the new generics would solve this problem quite elegantly.

"why would you want an artificial governer on your collections anyway? It's ironic that you quote the 'premature optimization' quote when that's exactly what the Java developers did when they made the methods on the 1.1 collections synchronized."--
What we "wanted" didn't matter back then. The collections came synchronized right out of the box. I can't speak for the design choices of the Java team, but we worked with what they gave us rather than reinventing the wheel; which oddly enough they did themselves with the next version of the JDK.

For the benefit of a couple of my friends who read this blog and happen to be vocabulary freaks, I have to point out that it's not 'ironic'; it is perhaps 'contradictory'.

"if I create a DataReader interface that has an initial implementation that reads from a file, should I throw an IOException to the client? What if I later decide to put my data in a database and now the code throws a SQLException? ... It's much easier and safer to wrap the low level exception into a higher level exception that the client can deal with. This prevents you from having to rewrite your client everytime you change the underlying implementation"--
An excellent example.

My sincerest thanks for your intelligent and constructive feedback!

Anonymous said...

I'm dubious that this is the same "Anonymous" that authored the first post [this follow-up is quite well articulated in comparison] but I'll give you the benefit of the doubt.The one and the same. I can be quite terse and similar to Hani (the comedic protagonist) as well as articulate when I need to be. I, like you, have had the need to present technical information to non-technical individuals. I've also worked as a teaching assistant for several undergrad Java/C++ courses where I had to use alot of non-computer analogies to get my points across.

Sorry if I came off as pretentious initially. I've had to suffer through alot of individuals who called themselves programmers over the years who pontificate inane ideas without any basis in reality or fact. My coworkers have suggested that I start a blog called "the grumpy programmer" but several other folks seem to have already cornered that market more adequetely than I could. I appreciate the problem you face--namely, maintaining a system that has probably outlived the originally intended lifetime of the stakeholders or authors. Been there, done that.

Cheers

Charles (cwhudakATcoxDOTnet)

Teflon Ted said...

"Sorry if I came off as pretentious initially"--
No hard feelings.

"My coworkers have suggested that I start a blog called 'the grumpy programmer'"--
Ha! I would definitely read it.

Well met, Charles.