Saturday, December 1, 2007

The Root of Friendship

Friendship, the effect results from this cause: confident recognition of your morality in another individual. The root of friendship is therefore common values. This fundamental fact raises two prerequisites that must be met before friendship can occur:

Prerequisite #1: All parties must know their own values. This relates to volatility of friendship. Someone that does not understand their values is volatile because they are a moral blank slate that may discover a conflicting value at any time. Before this perquisite can be met, time and effort must be dedicated to knowing your values.

Knowing a standard of value is also required to meet this prerequisite. A standard of value makes conflicting values impossible and demands moral continuity. A Catholic advocating abortion is conflicted in their standard of value. A Catholic advocating tithing is not. A student taking recreational drugs is conflicted in their standard of value. A student studying for a test is not. A husband unfaithful to his wife is conflicted in his standard of value. A husband being a friend to his wife is not. Without a standard of value no values can be known. When values are not known, friendships that follow will be volitile.

Prerequisite #2: Identification of your values in another party. This relates to the degree of friendship. A friendship is strengthened over time by consistently identifying with the values of the other party. Consistent identification of one's values in another individual is the root of trust among friends. Trust is a measure of confidence in knowing another individual's morality - it is knowing their system of values.

Friendship is not the product of sacrifice - it is not friendship that is earned by the sacrifice of what you value to what you do not. Friendship is not the product of common interests when principal goals are different. Friendship is not the product of non-action - if common values are present, a friendship will only occur if the effort of discovery is applied. Friendship is, and only is confident recognition of your morality in another individual.

Personal Update

I am amazed how fast December came this year. I hardly remember what I did in November because I was so busy meeting an end of the month deadline at work ... by the way you need go buy something from RugsUSA.com using GoogleCheckout!

Even with the long hours at work I still have had some time to do some fun things. I read some very interesting research related to the Sapir-Whorf hypothesis by Kenneth Iverson. His paper was titled "Notation as a Tool of Thought" and I highly recommend it to anyone interested in the philosophical aspect of linguistics, computer languages, and mathematics.

I also made it through a good part of "Objectivist Epistemology" by Ayn Rand. Atheism not considered, I am able to relate to much of her ideas. I chose this book in particular because I believe it will help me understand my own religious beliefs (this will certainly be a future topic - once I fully understand it myself).

Rebecca and I also decided in November that we were going to convert some of our assets into gold. This decision was based on the declining value of the U.S. Dollar, the intrinsic value of gold, and other factors. We purchased pure gold coins to be stored in a bank deposit box close to home. If anyone is interested in purchasing through Monex please let me know as we get a referral incentive.

Last but not least, I have had the opportunity to start learning about the Spring Framework, which I am using for an application. This application will track the price of gold and other currency real-time and valuate our investment daily based on market prices. It will also send out notifications to us if configurable conditions are triggered. Features will be exposed as web services so it should be easy to tie in other functionality as time goes on. I expect to be completed within the next week or so, I will give an update then.

Sunday, November 25, 2007

First Impressions of Spring

Over the long Thanksgiving break I decided to learn the Spring framework for a fun project I have been working on. My decision to use Spring was based mainly on a friend who said it was what I needed for my project.

Overall I like Spring. It is the glue of an application and makes the kinds of things (aka classes) configurable. One of the nice things Spring provides is an automatic answer to the question "where do I put that?" - a question that is supposed to be answered in the design phase of development. Spring also uses well known design patterns that make it easier to learn provided you know the patterns.

It was also nice to have many of the essential Java technologies all in one place. My application needs a web UI, a task scheduler, and a mailer all to run inside of a servlet container. The Spring framework already includes everything I need with Hibernate and Quartz.

One think I don't like about Spring is that it makes your application more prone to runtime errors. It is easy enough to pass a program through the compiler only to have it break during runtime because a bean uses a class in a jar that has not in the classpath. This isn't something I was used to in a strongly typed language such as Java. It would be nice if there was a tool that could run through my application and check bean/class dependencies. All things considered, for me this isn't a huge drawback - it is simply the price price that must be paid for all of Spring's flexibility. Hopefully it will motivate me to write better unit tests.

Another thing that was difficult for me was the number of dependent jars included with Spring. There were some inter-library dependencies that were time consuming to resolve. I would like to see all shared code compiled into one of the spring core jars and have every other module be self contained.

Wednesday, November 7, 2007

Ayn Rand and Atheism

How can Objectivism accept atheism - the nonexistence of god(s), when atheism presupposes that all knowledge is known?

Objectivism accepts that knowledge is gained by applying reason and logic to sensory data. What sensory data supports the nonexistence of god(s)? I assert that denying the existence of a deity is illogical because it is dependent on the false premise that all knowledge is known. By what process of non-contradictory identification does one take to deny for certain the existence of a deity?

Atheism itself is a contradiction. To believe fully in the nonexistence of something without knowing all knowledge is to take it on faith. If by definition agnosticism rejects the unknown (not the unknowable), I assert Rand would have been better suited to take an agnostic stance with respect to the existence of God.

Sunday, October 21, 2007

Working This Weekend at Home

I had to work from home about 6 hours this weekend. Our team is releasing the next major version of our product early November and we are to begin testing next week. This means that all changes need to be checked in by Monday which also means that I needed to finish things up over the weekend.

I enjoy working from home. I am physically more comfortable in the home office of my own design. I do not feel compelled to keep track of what I am doing, as close to 100% of my time goes to whatever task I intend to complete. I like my white boards, my wife, my 22" flat panel, my cigars, my cats, and my books all within reach. I generally feel more contemplative when I am in my home office which makes it easier to work through problems.

Often, when I leave work on a Friday knowing that something needs to be finished on Monday I feel tense and uneasy. These feelings are most extreme when there is some problem that has yet to be solved. This weekend, with Rebecca's help we were able to redesign a component that I have been struggling with all week in about 30 minutes; a feat only possible in the home office.

I would not give up my workweek to work at home full time, but I do enjoy the perks of the home office when the need arises.

Monday, October 15, 2007

How I Use log4j

Log4j is a 3rd party Java library that solves the huge (and under appreciated) problem that is application logging. I use log4j in all but the smallest applications as it is an invaluable tool to track down problems and recreate error conditions. As a general rule of thumb, I will use log4j in any program I write that somebody else is likely install and run. I absolutely love log4j and in my opinion it is the single most valuable tool for providing application visibility.

Even with simple console tools, it pays off to use log4j. Occasionally, I will get a question like "hey, tool X didn't work quite right a few days ago - what happened?". No problem, tool X was configured to send warnings and errors to the DailyRollingFileAppender. If I implemented logging correctly in tool X, I will have enough visibility to discover the problem and fix it.

Loading log4j properties

The first problem I run into is how configure log4j. I have the option to compile in configuration parameters, however by doing so I lose much log4j's vast flexibility. For most non-trivial applications I want to create a log4j properties file and load it when your application starts. For these reasons I prefer to pass the location of a log4j properties file into my program dynamically as a system property:

java -Dlog4jconfig=config/log4j.properties -cp "program.jar" Main arg1 ...

This solution is only acceptable for programs that are not executed by directly invoking the JVM. Things like setting the classpath and specifying system properties are a terrible burden on a user; therefore I recommend using a script or commons-launcher to handle the details of application startup. Further, by setting the log4j properties file name in a system property, I do not impact command line arguments specified by the user.

When it comes to the actual initialization of log4j, I generally have a block of code at the beginning of my program that looks like this:


String log4jConfig = System.getProperty("log4jconfig");

if (log4jConfig != null) {
PropertyConfigurator.configure(log4jConfig);
log.info("log4j initialized using properties file [" + log4jConfig + "]");
} else {
System.err.println("You must set system property log4jConfig");
System.exit(1);
}

When my program knows how to find the log4j properties file, I are now free to configure logging without having to recompile my application. My typical configuration looks like:

log4j.debug=false
log4j.rootLogger=debug, A1, A2

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.Threshold=INFO
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%p %d [%t] %c - %m%n

log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.Threshold=INFO
log4j.appender.A2.DatePattern=.yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.File=logs/application.log
log4j.appender.A2.layout.ConversionPattern=%p %d [%t] %c - %m%n

What to Log?

This is the real question. It is often difficult to decide what level of detail to send to your application logs. One of the most common logging statements in your program sends a caught exception to the logger. At this point I ask myself if the exception and stack trace will be enough to reproduce the error. If the answer is no, then I will log relevant inputs that caused the exception.

Assertions are another good place to add logging. Typically when my application is in the hands of users, assertions will be turned off. The only way to gain visibility into what happened is to log details of the assertion and what inputs caused the failure. Even if the assertion failure causes my program to terminate, a log can save me minuets to months when tracking down the problem.

Finally, I acknowledge there is always an else. Whenever I have an if without an else or a switch with an empty default condition, I consider the implications if my code hit the unhandled else/default. It often pays down the road to log "impossible" or "assumed" conditions such as these.

How?

Simply put, at the beginning of any class that supports logging, I will crate a static Logger object named log:

private static Logger log = Logger.getLogger(MyClassName.class);

One note of caution: I will undoubtedly copy/paste similar Logger initialization code throughout my program. I must make sure I change MyClassName to the actual name of my class. Forgetting to do so may not be caught by the compiler and may only show up months or years down the road when I actually need accurate information from the logs.

Lastly, when writing information to the log, I always enclose a concatenated string between braces. This makes empty strings more obvious and whitespace more readable:

log.error("Illegal condition [" + illegalCondition + "] occured");

Conclusion

I have barely scratched the surface of log4j's capabilities. For more information I highly recommend purchasing the log4j book for $19.67 USD. This text is an excellent reference and has proven to be quite useful to me. I am very interested in how others use log4j; I would appreciate a comment if you feel you have your own noteworthy log4j tips.

Sunday, September 30, 2007

How I Spent My Time at Work the Past 7 Weeks

Over the past 7 weeks between 8/6/2007 and the end 9/21/2007 I conducted an experiment in which I tracked time spent on different tasks at work. Weeks were considered between 7:30 AM and 6:00 PM Monday through Friday. Overtime was not considered. The summaries are given below as a percentage of total time tracked for that particular week. For example, if I only tracked 30 hours worth of tasks during a week, then time spent per task was calculated as a percentage of 30 hours.

My goal is to gain a deeper understanding of the software development process at my organization, to quantify assertions I hold regarding my activities, and to empirically measure changes by way of historical context.

Below are the summarized categories over the 7 weeks with a short description:


Development: 48%

Development is the task of software construction. I count development time as reading, writing, or debugging code.

Customer Support: 12%
Customer support related tasks are counted as the time I spend on requests initiated by our customers. This generally involves communication and log mining activities.

Time in the ROC: 08%
Due to the secure nature in which we must conduct business, all access to our production machines must be done in a secure location known as the remote operations center or ROC.

Meetings: 07%
No explanation needed.

Report generation: 05%
Creating both internal and customer reports.

Team Help: 05%
Receiving or giving help on specific technical issues. Team meetings were not categorized here.

Design: 04%
Software design activities.

Conference Calls: 03%
No explanation needed.

Testing: 02%
Software testing activities.

Integration: 02%
Development time spent integrating our software product into a customer's system.

Requirements: 01%
Requirements gathering activities.

Email: 01%
Responding to email messages.

Documentation: 01%
Writing technical documentation.

Releasing code: <1%
Releasing new code into our production environment.

Help desk: <1%
Internal help desk requests.

* * *

Analysis

Development Time
I was surprised to see how much time I actually spent time writing code. Although I am a software developer, my perception was way off from what the actual data shows. I think that any developer spending almost half of his or her time coding is pretty good. One factor that may be altering my development time perception is the number of interruptions incurred when coding, I may track this in the future.

Customer Support
This was fairly low but if I was a manager, I would keep a close eye on how much customer support my developers are providing. If it gets up around 15% to 20% it may be time to hire or train level 1 support personnel. Customer support specialists will always be less expensive than software developers.

Meetings & Telephone Calls
As a general rule I dislike meetings and conference calls. My company has a weekly staff meeting every Monday for 30 minuets to get everyone on the same page. I feel that very little if any of my time is wasted in meetings. When we do meet, an agenda is followed and everyone stays on topic. While we are not quite the model of a Manager Tools meeting, I think that we still score an A- when it comes to meetings. Kudos to excellent management.

Telephone calls are a different story. While 3% may seem like a small number, nothing is more effective at getting me off track than a telephone call. A conference call with a customer is rarely a discussion on the thing I just happen to be working on and usually a call requires me to spend a short amount of time preparing. While the call may only be 20 minuets, there may be action items and/or new priorities that cause further disturbance in my schedule.

Requirements and Design
After some reflection on the proportionally small amount of time I spent on requirements, I conclude that most of the requirements have been either already well defined or self-evident (bug fixes). While my role is not that of a systems analyst, I was a bit surprised at how little time I spent thinking about requirements.

Design is another matter. For better or worse most of my design happens as I am coding. There have been a few exceptions to this, however the design while you code methodology is certainly the norm. Coming from a software engineering background this was a red flag and is a topic I will be meditating on in the future.



Conclusions

This was an extremely interesting endeavor for me. I am looking forward to the feedback I receive when I give this data to management. Going forward, I plan to continue tracking my times and refining my methods (mostly self-discipline).

Thursday, September 27, 2007

The Best Type of Customer is The One That Makes You Better

I have had to work with cryptography and digital signatures exhaustively on an application level. One of the hardest things I had to do was create and verify digital signatures based on data being passed around via HTTP. I quickly learned in practice what I already knew in theory: characters are not bytes!

Case in point. One of our largest customers came over to our platform from a competitor that was getting out of the payment business. This customer was very concerned about digital signature verification, as this had been a long-standing problem with our competitor. I was tasked with building an interface into our existing application for this customer so they would not need to make any code changes. Testing went well and we hit our go live date.

It quickly became apparent in production that too many international transactions were failing the digital signature check - the same type of problem this customer had been experiencing all along. Our cryptography expert suggested that I explore character encoding as a source of the errors. After some testing, it amazed me how easy it was to inadvertently change data while passing it from country to country, application to application, and programming language to programming language. Character encoding seemed very likely to be the avenue to the solution. Unicode, ASCII, UTF-8, big and little endian - there were a menagerie of topics related to character encoding I needed to consider. After spending several days trying to understand the complexities involved with mapping characters to numbers, I still felt that I had only an elementary understanding of character encoding.

After frantic research and troubleshooting, the problem was caused by the translation occurring between our web and application tiers. The customer was encoding the data in UTF-8, signing it, and passing it along to us for verification. We were taking that data in UTF-8 on the web tier, but in our application it was decoding as US-ASCII. The final fix consisted of (1) altering a few characters on one line of code and (2) me becoming a slightly better developer.

Lesson learned: From a developer's perspective, the best type of customer is the one that makes you better.

Saturday, September 22, 2007

The Mac as a Software Development Platform

Many of my co-workers (and people in general for that matter) find it strange that I use a MacBook Pro as my primary development platform. The two main camps of developers I have encountered either lean towards Microsoft Windows or some flavor of UNIX. Most of them have never even considered using a Mac for software development. While I acknowledge that some tasks are platform dependent (ASP.NET for example), many tasks allow developers the freedom to choose their own environment.

The rest of this article will elaborate on features the Mac has that makes it a good development environment. In the conclusion I will speculate on reasons why I think the Mac has not become popular among the development community.

Where am I Coming From?

Most of my development tasks involve writing Java code and solving technical problems. I work in the payment industry and our customers use just about every platform under the sun. My company produces software written in Java, ASP, ASP.NET, Perl, PHP, and ColdFusion.

Security

By default my MacBook Pro was fairly open. No password was required at login and account names were displayed on startup. It was easy enough to reconfigure and go back to a more traditional UNIX login situation that prompted for a user name and password. In addition, I was able to easily and transparently encrypt my home directory with file FileVault. Finally, the MacBook uses ipfw, the FreeBSD firewall. Ipfw can be configured through a tool in System Preferences and optionally its full power can be exploited through the UNIX terminal (more on this later).

Text Processing

A good portion of my time during the week is spent on text processing tasks. Usually I am creating a report, mining log files, or changing character encodings. Darwin conveniently provides almost every tool I need such as sed, awk, grep, Perl, cut, and iconv. A great way to impress someone who brushes Macs off as a computing platform for hippies is to open up a terminal and burn through an ugly log file with a only few commands.

Darwin Ports

I have always liked the OpenBSD ports system. While not exactly the same, Darwin Ports makes it very easy to install open source software on the Mac. I have used Darwin Ports in the past to quickly create a UNIX environment I am accustom to without having to worry about dependencies and compatibility.

Java

Mac OS 10.4 comes with JDK 1.3 through JDK 1.5. Swing components are beautiful, all the standard tools such as Ant and Javadoc are bundled, and documentation packs are free to download on Apple's developer site.

X11

One of the things that surprised me the most when I purchased a Mac was how painless it was to get X11 set up. Although I was slightly disappointed that it was not pre-installed, Apple did provide the X11 package on the companion CD. After a few clicks, X11 was automatically configured and running properly. X11 is another essential programs that I have grown accustom to. By installing X11, an entirely new category of applications can run on a Mac.

VPN

I have never met a VPN I couldn't talk to. I am able to connect to my corporate VPN via PPTP on the Mac at least as easily as on a Windows PC. My previous employer used SSH tunneling as a point-to-point VPN. No problem on a Mac, OpenSSH is installed by default.

Windows Remote Desktop

Microsoft provides a free version of remote desktop for the Mac so it is easy to work from home or access a Windows PC. One of the nice things this allows me to do at work is to hook up a second monitor and connect to my Windows PC via Remote Desktop. By doing this, I have a duel head Mac with a connection to a Windows box that can be controlled by a single keyboard and mouse.

IPFW

I mention this specifically because it helped solve a particularly difficult problem. In a nutshell, we were attempting to improve the performance of our primary product. Our thought was that network latency was causing connection delays when the application's threads were entering a synchronized block. We ended up configuring ipfw on my Mac to introduce controlled network latency that made it possible to test and eventually correct the synchronization problem.


* * *

In conclusion, I assert that there are three factors that work against the Mac as a developer platform:

  1. Until OS X, the Mac was limited when it came to development. For me, limited software availability made Macs an ugly alternative to Windows or UNIX. I believe that Macs are still haunted by the stigma they carry from the pre-OS X days.
  2. When Apple switched to Intel processors it opened the possibility of running Windows in a non-emulated environment. Windows runs well on Intel Macs, Apple even provides Windows drivers for all their hardware. However before this recent move to Intel, Macs used PowerPC processors which would likely have caused unfavorable compatibility issues in the eyes of software developers.
  3. Price. Macs are about as expensive as high-end PCs. This is their biggest negative in my opinion. Since OS X is UNIX-based, a Mac platform is more attractive to open source developers. However, many open source developers may not want to pay for such an expensive machine.

Saturday, September 8, 2007

Higher Education In The Software Industry

After finishing graduate school I felt quite eager and prepared to enter the work force. For the most part I was very far beyond many of my classmates in many academic disciplines except when it came to real world experience. At the time, I never gave much thought as to where a graduate-level degree would take me. Having been out of school for some time, I believe the purpose of a college level education is a combination of items in the list below:

To provide a way for individuals at a novice skill level to break into the software industry.

Software is a relatively new discipline that under most circumstances does not require any special certification to practice. Unlike in civil engineering where by law formal certification must be obtained before signing off on the design of a new structure.

A self-motivated person may educate themselves at a local bookstore and has the potential to be just as successful as the college graduate. However, for a true software novice who may not know where to begin or what to focus on, time may be better spent in a program designed to start at the beginning.

Reference: check out SWEBOK for a collection of disciplines a software engineer can be proficient in.


To make yourself a more attractive hire by reducing the risk a future employer takes when it is not ideal for them to pay more for an experienced candidate.

My former boss and chair of the computer science department once said to me that getting a Ph.D. is a lot like graduate school, except it shows that you can survive. Although many graduates leave school with little work experience, by earning a degree you have proof that there exists various qualities within you to:

  1. Personal responsibility
  2. The will to finish things
  3. An interest in a given discipline
  4. Forward thinking
This gives an employer a bargain opportunity when hiring. While a person with five years professional experience would almost certainly be more proficient than a recent graduate, the employer would also need to pay for that proficiency with a higher salary. By hiring a recent graduate the employer can offer a lower salary at the cost of taking on some risk. This is why a high GPA is crucial, it is an indicator that you represent a reduced risk and are therefore a more attractive hire.

To produce better research.

This is especially true at the graduate level. I was not training to develop great software systems, I was training to produce research on topics related to software. I concede that not everyone studying computer science wants to be a software developer. There are those who want to be on the cutting edge of some of esoteric technologies. Higher education trains you to do produce research.

To pursue a professional career in academia.

The next time you visit a college make note of faculty who have earned their Ph.D. If they look like they are in their late twenties to early thirties, chances are their primary chosen professions is a career academic. Obviously higher education is a requirement for a career academic.

I was close to choosing a career in academia. Almost immediately after graduation I was teaching many of the courses that I had to take only a few short years ago. For financial reasons I decided not to pursue the academic path at this time in my life. For better or worse there is a gap between academia and the business world. I was mostly ignorant to this fact and wore a wet blanket for a few months after graduation. Unpleasant as it was at the time, I now appreciate the fact that I have insights into both worlds.

To participate in education for its own sake.

I never quite understood this one but nevertheless I saw individuals accumulating degrees without any apparent reason.

To have a social experience.

I believe this is a symptom of either immaturity or short-sightedness. Regardless, there are those that decide to participate in higher education because of the social opportunities associated.

Tuesday, September 4, 2007

Goals for Today

  1. Appreciate God
  2. Commit to learning something of value
  3. Be honest
  4. Handle a situation better than I would have yesterday
  5. Be transparent
  6. Experience a paradigm shift
  7. Don't break anything
  8. Think about new goals for tomorrow
Goals for tomorrow:
  1. Appreciate God
  2. Commit to learning something of value
  3. Be honest
  4. Handle a situation better than I would have yesterday
  5. Be transparent
  6. Experience a paradigm shift
  7. Don't break anything
  8. Ask someone to explain something I don't understand
  9. Think about new goals for tomorrow

Thursday, August 30, 2007

Technical Litigation

Disclaimer: I do not take credit for this term, I first had it explained to me by our vice president of operations at my current employer.
Everyone thinks they are special. You can have an application doing the same thing for hundreds of customers and each one thinks that the unique problems they are experiencing must be your fault. Quite simply, technical litigation is the process taken to prove that [technical situation X] does not lie within your jurisdiction of control.

Recently, I wrote two programs for the single purpose of technical litigation. I spent approximately 3 hours of my 12 hour workday writing code to prove a point. The first program simulated the digital signature component of our testing environment. In reality, after I pulled the correct data the coding only took about 30 minuets. Still it was time I could have spent doing other tasks that would have a more long-term impact. The second program was designed to prove that the way we base64 encode some binary data was correct. This second program compared byte lengths and hashes of the decoded strings from four different base64 decoder implementations.

To be fair, this is an atypical example but I would say that roughly 10% of my time as a developer is spent dealing with issues of technical litigation. I am admittedly curious how much other organizations deal this issue - particularly among developers. During the course of technical litigation I have learned a few things from my experience:

#1 I tend to pursue problems differently when I hold the premise that I'm not the one at fault.

I can't really say why, but I have a tendency to be more methodical with problems that I don't think I caused. It is almost as if I have a clearer mind when I am looking at someone else's mess. Maybe it is the the fact that personal emotion is taken out of the situation. Maybe I am not distracted by the possibility of learning a hard lesson at the end of the day. Maybe it is simply my professional inexperience. I cannot say definitively, but the fact remains that I approach problems of technical litigation very differently.

#2 My job is to attack the problem, not the customer.

This is not something that I have a major issues with, but I can see that there is a natural competitive tendency to beat the other side when trying to prove a point. When the other side helps pay your salary then it it important to look at them as a partner who ultimately wants the same thing you do: for the problem to go away.


#3 Pointing fingers is never more important than moving on.

I learned this by observing breakdowns in #2. Whether you are a developer, a customer, or a manager, accepting responsibility is often a difficult emotional process. The end goal of technical litigation should always be a problem resolution. Technical litigation should be though of as simply a middle process to determine who needs to do the solving. Therefore, once the responsible party has been identified, there is no need to dwell in the technical litigation phase. Pointing fingers and arguing will delay the problem solving process and will not benefit either side.


#4 Admit when you are wrong.

This closely ties into point #3 but is in my opinion the most difficult aspect of technical litigation. The software industry attracts many individuals who have a dominant "C" personality (refer to the DiSC model). The high C personality values accuracy and detail which gives them an advantage when working with complex technical concepts. Given that accuracy is important to the C, it is often much more difficult to accept being wrong.

Tuesday, August 28, 2007

Application Visibility

So it's your first week at the new job and you are charged with building a new product for one of the largest customers in your organization's history. After a short period of flattery, the gavel that is reality smacks down hard to let you know that your ass is on the line. You have the much needed guidance from your team and extremely competent management that understands software - but ultimately success or failure is at your doorstep.

So you are in pretty deep - what's the plan?

  1. Carefully test your code
  2. Perform code reviews
  3. Put your pride away and ask for help - even if you think you have the right answer you may not!
  4. Be honest
Fast forward to a few days after you have successfully released your application into production. You stuck to the plan: you tested very carefully, you had your peers scrutinize your work, you asked for help, and you reported the state of the project honestly and consistently. The customer was surprised that things went so well. Congratulations, you just did the impossible: exceeding expectations in a situation where things could have easily gone horribly wrong.

After a week in production some issues are discovered. It's your application so you need to fix it. Easy enough right? Just plow through thousands of log entries and piece together what went wrong. Not exactly because you completely neglected to think about what types of problems might occur in production, therefore you are not logging the information needed to investigate the customer's complaint. You have no visibility into your application. The only course of action to take at this point is to retroactively update the code in production to give you the visibility needed to solve the problem.

The mistake was costly in terms of personal pride and hardship, but the lesson is valuable. You learn that there is no way of telling what an application is going to do in a high volume production environment where real data is being passed in. Thus, it is absolutely essential that you build in enough visibility to resolve issues that appear in production. You also learn that nothing of value comes easy.

Sunday, August 26, 2007

Beware Of The Technology Advocate

Windows or Linux? RedHat or Ubuntu? GPL or BSD license? vi or emacs? JSP or ASP? I can't tell you how many times I have had a discussion with a friend or co-worker that starts like this:

"You use technology x?! ... Did you know about technology y, its way better..."

or the ever popular negative approach:

"System x sucks, system y can do..."

I hate such discussions, mainly because (generally) both sides have a valid point. Technology does something to us when we learn how to use it to solve our problems. Suddenly the hot new whatever becomes useful, and despite its quirks makes us feel so good that we have to advocate its usefulness to the rest of the world. This would be fine if there were no technological overlap. Fortunately for all of us technologies do overlap.

Enter conflict. It is inevitable whenever two technology advocates get together who have similar strategic objectives but different technological toolboxes. The conversation will usually start out like a game of chess but typically ends in a pissing contest. Nobody benefits from this and everyone leaves irritated. So if you like your Windows Vista work environment and that obnoxious Linux guru comes by your cube to harass you, try to keep a few things in mind:

  1. Technology shouldn't be a religion, so don't treat it as such. Unlike with your religion, technologies have gray areas that overlap. Don't look at competing technologies as exclusively good or exclusively bad.
  2. Java is paying for my home. There are a lot of people who swear Java sucks (just ask Google). But I write Java every day, I get paid good money, and I like what I do. My customers are happy and my company is making money. Despite the laundry list of reasons why Java sucks from very competent people, it is still self-evident that Java doesn't suck.
  3. Is a drill better than a chainsaw? A prudent person could not answer this question without knowing specific situational information. However, the technology advocate will swear that he or she has used a chainsaw before and it worked every single time: faster and with better results than your drill. Don't let the advocate talk you in to installing a wall anchor with a chainsaw.