Always Get Better

Archive for February, 2008

Programming Doesn’t Mix With Family

Monday, February 18th, 2008

Back in 2006, George Alexander detailed a great list of traits essential for successful computer programmers. In this entry, we will look at those traits and see how they apply (or not) to the family life of a computer programmer.

In Canada, the Ontario government decreed the third Monday in February would be a holiday known as “family day”. This ends the decades-long stretch from January through March known to Canadians as the “dead zone” – the longest unbroken span of work weeks of the year. Nobody is complaining about a long weekend lightening the dreary winter months; except of course the four million or so workers who don’t qualify for the holiday, but that’s another story altogether.

Computer programmers don’t all fit the secluded, socially-inept stereotype. But for those of us that have families it can be difficult to shut off at the end of the day and become “human” again. Perhaps the shift that has to happen isn’t as extreme as, say, a soldier who comes home from overseas and has to go back to being a functional family member. All the same, the thinking needed to fulfill the duties of an analyst/programmer isn’t always compatible with the thinking needed to helm a family.

1. It’s not about computer languages

Leave you C++ code on your computer at work. It took you years of study, trial and error to warp your mind and destroy your soul enough that programming was opened up as a source of income. Don’t put your family through that.

I’m not worried so much about the blank looks on their faces and their faked encouragement when you go off all proudly about the sorting algorithm you finally managed to optimize. What about the day when they actual understand some or all of what you’re talking about? You’ll feel horrible for killing part of what made your loved ones human.

2. Drive and passion

Hopefully some of the passion that drives you to excel as a program is also present in your personal life. My father-in-law comes home from his job at 2pm, takes a short nap, then works until 1am improving his house and spending time with his wife and kids. His household is one of the warmest and happiest I have ever had the pleasure of being part of.

My father-in-law realizes that what you have now is always temporary – don’t take your loved ones for granted because you don’t know for sure if you will still have them tomorrow. Everyone would benefit from living every day as if it was their last; if that were to happen, computer programming may not seem all that important anymore.

3. Dealing with Change

The nature of IT careers requires us to constantly be aware of “the next thing”. Things always get “better” so in order to provide the best solution we must accept changing ideas as the norm.

In many ways, this is totally incompatible with family life. Families like stability – you’re responsible to come home from work with a positive outlook, provide financial security, consistently enforce household rules… and the list goes on. To provide the best family life possible, you must take reasonable actions to protect your family from change.

Even a move can be hard to deal with, especially for your children. I attribute this to why many workers choose to commute long distances rather than finding homes nearer to where they work. I once met a man on the Ottawa-Toronto train who was commuting to his day job – spending all week in Toronto and coming home to his family on weekends. He was involved in a new startup and wanted to make sure it was going to take off before dislocating his family; he was protecting them from unnecessary change.

4. Break It Down

Every day we apply the divide-and-conquer approach to achieving large tasks. We don’t “go to work”, we have a shower, get dressed, get in the car, drive to the office, park. Likewise, when we show our kids how to repair drywall, we don’t show them the final result and say “make it look like that” – we show them the steps it took to get there.

As important as breaking tasks down to their components can be for solving large problems, it doesn’t have as huge a place in family life as it does in work life. Your family is not a complex set of problems needing analysis and design – you really need to understand how the things you say and do today affect those around you in the long term. Day-to-day financial planning is disastrous – the big picture is far more important that individual transactions.

5. Do Not Reinvent the Wheel

A disciplined programmer knows that quality code can be re-used in other programs – rather than solving very similar problems again and again it is possible to create a single solution that can be copy & pasted or simply linked into the next project. It took thirty years of scientific reasoning to advance our field to this stage; unlike our well-defined little jobs, family life must be constantly evaluated and redefined.

Once my wife and I announced we had a baby on the way, everyone began crawling out of the woodwork to give us their “advice” for pregnancy and raising children. Of course, there is no code reuse when it comes to this stuff – every parent and child is different and it’s our job to figure out what works best for us.

6. Practice, Trial and Error

Here is one area where work skills can transfer over to your personal life. Rather, I would suggest that when it comes to trial and error, the skills you learned in your personal life are serving you well in your programming career.

Do I have to go out of my way to say that no one is perfect, and everyone can always get better with trial and error? Try new things, find out where you made mistakes, try again.

Although not everyone is or wants to be, I’m married now. As I was growing up, every failed relationship taught me a little more about myself and about how I should be treating women. In a sense, each ex-girlfriend was really “practice” for the next. The constant re-evaluation seems to have paid off. The point is – never stop trying to improve, because there’s always room to get better. We have to own our failures as well as our successes.

7. Mentorship

If you have children, they depend on you for food, clothing and shelter. More importantly, they depend on you for guidance – even when they think they know better than you do anyway. As a parent, your job is to be in control and have all the answers even when you aren’t in control and when you don’t have any answers. Going back to #3, you must be a constant source of stability.

The same is true if you don’t have kids yet. Everyone has their own problems and no one needs or wants to solve yours. The world is too full of people who won’t take responsibility for their own thoughts and actions. Solve your issues on your own time and just enjoy being with other people.

As Fernando Lamas (the real one) said, “It is better to look good than to feel good.”

8. Be Open to Criticism

When we deliver a project to a client there is an expectation that the results don’t contain a lot of problems because we have gone through a quality control process to arrive at the best possible solution. Part of that process involves having someone else look at your design and critique it.

In the real world, we get criticism from a myriad of sources whether we solicit it or not. We don’t ask family members whether they approve of the way we installed our cabinets but we get their comments anyway.

No one goes out of their way to hurt or put down someone else – at least, this is what I would like to believe in my naive little understanding of the world. Even the handy family member is trying to be helpful when he complains of how he can’t fathom why you would use plywood instead of… you get the idea.

Like anything else, it all comes down to filtration. Take the good with the bad and don’t let people get under your skin. Sometimes they may just as well offer a tidbit that you can grow on.

9. Bug Off!

As with seeking criticism, software development involves a lot of self-starting even when it’s not strictly requested. Case in point: bug testing. No self-respecting programmer takes the design at face value, programs it, and submits it for testing without evaluating the product in the project’s grand context. We desire our work to be perfect to a fault and when it isn’t our ego takes a blow. Computer programmers especially tend to be obsessive compulsive about having their solutions in perfect order with no strings left untied.

I warn you – the obsessive perfectionist view that helps win promotions at work does nothing for your personal life. Girlfriends, wives and especially kids don’t share your drive for order. You have learned many of your intuitions and must learn how to turn them off when you get home or you will slowly go insane.

A few examples of things that will turn your crank but are worthless to normal people (unlike your mutant self):

  • The kitchen was not tidied during cooking
  • The kids colouring books when shapes were only partly filled in, or coloured over the lines
  • Report cards with any non-perfect grades
  • People not trying to get every last coin in world 1-4 of Super Mario Bros. 3.

10. The Significance of Communication

Computer programmers are not like normal people. Normal people don’t obsess over math problems. Normal people don’t do the mental acrobatics needed to understand pointers and floating point precision. Most people don’t care about x = x+1. Those who do know that at face value it is meaningless (0 = 1?) and can’t comprehend why you would choose a profession in which the most important calculation is nonsense.

So don’t try to explain your work to your family. At best they won’t understand what you’re talking about and at worst you’ll ruin their minds like you have ruined yours. If your kids grow up to be computer programmers they won’t thank you for it.

SQL Connections in ASP.NET – What you learned is WRONG!

Friday, February 15th, 2008

When we learn how to open and use a database connection with ASP.NET, as with any other programming concept in any other programming language, the simplified version used to explain what’s going on is not truly representative of the quality professional code we will one day be expected to write.
Opening and Closing Connections

Case in point: managing of sql database connection resources. How many of us learned to write something like this:


// Create a new SQL Connection object
SqlConnection conn = new SqlConnection( connectionString );

// Open the connection to the database
conn.Open();

// Create a new SQL Command
SqlCommand cmd = new SqlCommand( “DELETE FROM BabyNames;”, conn );

// Execute the command
cmd.ExecuteNonQuery();

// Close the database connection
conn.Close();

Sure it’s easy to follow, but if you deploy that on a moderately busy server you are going to make your client very unhappy.

Dispose Resources

SQLConnection and SQLCommand objects reference unmanaged resources, meaning the C# garbage collector has no framework knowledge about your object. Since these classes both implement the disposable interface it is important to call the Dispose() method in order to correctly free your application’s used memory.

So our code gets updated to look like this:


// Create a new SQL Connection object
SqlConnection conn = new SqlConnection( connectionString );

// Open the connection to the database
conn.Open();

// Create a new SQL Command
SqlCommand cmd = new SqlCommand( “DELETE FROM BabyNames;”, conn );

// Execute the command
cmd.ExecuteNonQuery();

// Dispose of the command
cmd.Dispose();

// Close the database connection
conn.Close();

// Dispose of the connection object
conn.Dispose();

Trap for Errors

What happens if there’s a problem, and your code fails to complete? If your application crashes before your objects are disposed, you are left with the same effect as if you had never disposed your objects at all!

Fortunately, C# includes the try … finally reserved words. If anything within the try { } block fails, the finally { } still executes. We can easily apply this to our program code:


// Create a new SQL Connection object
SqlConnection conn = new SqlConnection( connectionString );

try
{
// Open the connection to the database
conn.Open();

// Create a new SQL Command
SqlCommand cmd = new SqlCommand( “DELETE FROM BabyNames;”, conn );

try
{
// Execute the command
cmd.ExecuteNonQuery();
}
finally
{
// Dispose of the command
cmd.Dispose();
}

// Close the database connection
conn.Close();
}
finally
{
// Dispose of the connection object
conn.Dispose();
}

For my own part, I prefer the using keyword. We can include a using call anywhere we would ordinarily use a disposal object. When the code is compiled, it behaves the same as try … catch, but leaves our program code much more readable.

Even better, we don’t even have to bother calling Dispose() because it does it for us!


// Create a new SQL Connection object
using ( SqlConnection conn = new SqlConnection( connectionString ) )
{
// Open the connection to the database
conn.Open();

// Create a new SQL Command
using ( SqlCommand cmd = new SqlCommand( “DELETE FROM BabyNames;”, conn ) )
{
// Execute the command
cmd.ExecuteNonQuery();
}

// Close the database connection
conn.Close();
}

Slick.

Open Late, Close Early (like a bank)

There is one more thing I would add to this. Creating objects in memory takes time. Although it happens in fractions of a second too fast to be detectable by us, it’s important not to waste processing time wherever possible.

Whenever we Open() a database connection, we expect to use the database right away. If we then create an SqlCommand, we’re wasting the open connection’s time. It’s as if we pick up the phone and listen to the dial tone while we then flip through the white pages looking for the number we want to call.

Let’s change our example code so we will now Open() at the last possible opportunity, and Close() right away when we’ve made our call:


// Create a new SQL Connection object
using ( SqlConnection conn = new SqlConnection( connectionString ) )
{
// Create a new SQL Command
using ( SqlCommand cmd = new SqlCommand( “DELETE FROM BabyNames;”, conn ) )
{
// Open the connection to the database
conn.Open();

// Execute the command
cmd.ExecuteNonQuery();

// Close the connection to the database
conn.Close();
}
}

In the end, the program code we wrote is very similar to the newbie code we started with. However, we’re now protecting our system from memory leaks, and we’re protecting our database from wasted clock cycles. Our code is easy to read and stable.

How to Create Full Text Search Using mySQL

Thursday, February 14th, 2008

Search is one of the most basic features visitors expect when they come to a web site. This is especially true in e-commerce where your ability to make a sale is directly related to your customer’s ability to find the product they’re looking for.

Using Third-Party Solutions

Many first-time site owner choose to go with Google Custom Search because of its easy setup and because of Google’s incredible indexing reach and results. I don’t like the standard edition of the Custom Search because of the branding – your search results advertise Google and provide links to competing content. For an e-commerce site to lose control of such a critical function, the results can be costly.

Don’t Give Up Control

Especially in e-commerce, it is best to never give up control over any content. Advanced users may choose to ignore your site’s search tool and use Google to get at your content anyway (via the site: directive) but in the general case there is great potential to keep selling useful products to your potential customers even while they search your site for other items.

Incorporating a decent search tool into a web site using PHP is dead simple. All it involves is a database table with 3 or more rows and a little bit of an eye for layout. Even if you don’t consider yourself a designer, having a look around other search engines will give you a feel for how results should display.

Creating the Search Tables

Let’s get started. Our simplistic database table (PRODUCTS) will consist of the following columns:

Column Name Data Type Description
intID int Product ID and Primary Key
vcrName varchar(25) Product Name
txtDescription text Product Description
vcrPhoto varchar(40) Path (URL) to product photo

Obviously this is just a simplified example, but the product ID, name, description and photo should be enough for the purposes of our demonstration.

The SQL to create the table looks like this:
[source:sql]
CREATE TABLE PRODUCTS
(
intID int auto_increment,
vcrName varchar(25),
txtDescription text,
vcrPhoto varchar(40),
CONSTRAINT PRODUCTS_pk PRIMARY KEY ( intID )
);
[/source]

Add the Full-Text Index

In this example, we’re interested in searching the name and description fields of our products. In order to add the full-text index to our table, we use the ALTER TABLE command:

[source:sql]
ALTER TABLE PRODUCTS ADD FULLTEXT( vcrName, txtDescription );
[/source]

Alternatively, we could have created the index along with the table in our original CREATE statement like this:

[source:sql]
CREATE TABLE PRODUCTS
(
intID int auto_increment,
vcrName varchar(25),
txtDescription text,
vcrPhoto varchar(40),
CONSTRAINT PRODUCTS_pk PRIMARY KEY ( intID ),
FULLTEXT( vcrName, txtDescription )
);
[/source]

Searching For Text

Now that the index has been created, we can go ahead and search the database. To activate full-text search, we use the MATCH () AGAINST () syntax like this:

[source:sql]
SELECT intID, vcrName, txtDescription, vcrPhoto
FROM PRODUCTS
WHERE MATCH( vcrName, txtDescription ) AGAINST ( ‘search terms here’ );
[/source]

That’s all there is to it! Anyone with access to a mySQL database should be able to incorporate search into their sites without too much difficulty. Of course this is a very basic introduction, but should be more the sufficient to get going with.

Maintaining SQL Connections in ASP.NET

Monday, February 11th, 2008

There is a lot of conflicting advice with regard to the proper way of using SQL connections in web work.  The two main schools of thought are:

 

  1. Open a connection once, use it for everything and free it when the page request is complete.
  2. Open a connection only when it is needed, then fre it right away.

 

It All Comes Down to Speed

Any operation performed by the server has a cost associated with it.  Loops and counts happen on the CPU and are incredibly fast.  Caches are stores in system memory and seem fast but are in fact thousands of times slower than direct CPU operation.

 

As far as internal server access goes, reading and writing to the hard drive is representative of the most expensive operation performed by applications.  If possible, memory is oftent he best storage medium for program instructions.

 

Consider Database Access Costs

Databases live in a realm somewhere between hard drives and memory.  A good DBMS reacts to requests by storing execution plans and data in system memory thereby reducing the amount of time applications have to wait for information to load off the hard drive.

 

In terms of execution costs, connecting to the database is up there with reading from the hard drive.  Is a database connetion isn’t needed, don’t create one.

 

Which is better?

Considering the high price of connecting to a database, which of the following makes the most sense for our web application?

 

  1. Creating the connection to the database, performing all operations, and closing the connection after the is complete, org;
  2. For every request, creating a connection, executing a query, then closing the connection.  Repeat every time a new piece of information is required.

 

In classic ASP’s ADO, #1 was the best option.  In modern ASP.NET’s ADO.NET, #2 is the way to go.  That was a trick question.

 

Classic ASP – ADO

Using classic ASP, the developer has a great deal of control over the sequence in which their code will run.

 

It’s very easy to open a single connection at the top of a web page and use it for all of that page’s database operations.  At the end of the page, the developer writes code logic to free all record sets used, close memory objects, and release the connection.

 

ADO.NET

When writing code for ASP.NET, we strive to be “good” .NET citizens.  We are given a lot of power to write application logic never before possible on the web, and we are asked to relinquish some of our finer-grained control over resources.

 

Generally, managed resources benefits the programmer by freeing them to focus more on the business requirements of their project rather than their specific environment’s implementation.  Database connectivity, however, is a concept that has to be updated to fit the .NET paradigm.

 

Whereas before we controlled when database resources were released to the system, now the garbage collector has taken responsibility for the task.  If we open a database connection when the page request begins, we have no real guarantee it will be released in a timely manner when the page request completes.

 

This means the only way to prevent the server from running out of connections is by creating, using, and immediately freeing them every time we want to retrieve information from the database.

 

What about the cost of execution?  One would assume we’ve taken two steps back but ASP.NET introduces connection pooling for this situation.

 

Connection Pooling is your friend

Any time a connection is requested, the server looks to a special pool of memory objects where it keeps previously used database connections.  If there are any connections no longer being used, the server will return those unused connections before creating a new one.

 

Essentially the server only incurs the cost of creating a connection the first time it is used, or whenever demand for a particular application spikes.

 

When our program is done with the database, it releases the connection back into the pool for other requests.

 

Never Create Global Connection Objects

The morale of the story is: work with the .NET framework and let it do its job.  As long as we are willing to let go of old ways of thinking and adapt to the new technologies, our programming lives will become ever simpler.

 

Every day web applications grow in their complexity.  Fortunately the power and capabilities of the tools we have available also continue to improve.

 

Expect databases to continue driving bigger and better web presences.  The more skilled we become at working with them the more likely we are to succeed in creating stable, reliable and scalable applications to take advantage of them.

Breaking Java’s Rules: Instantiating an Interface

Friday, February 8th, 2008

Here’s a geeky party trick:

Abstract classes in Java cannot be instantiated. Here we’re going to consider ways in which a button can be programmed within a JPanel. ActionListener is used to react to the button event, but ActionLister is an interface (pure abstract class) so in order to use it you have to derive a class from it and implement actionPerformed.

For example, you can’t do this:

[source:java]
ActionListener buttonListener = new ActionListener();
[/source]

You have to do this:

[source:java]
public class ButtonListener
{
public void actionPerformed( ActionEvent event )
{
}
}

ButtonListener buttonListener = new ButtonListener();
ourJButton.addActionListener( buttonListener );
[/source]

However, this code is valid:

[source:java]
ourJButon.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent event )
{
}
} );
[/source]

What’s going on? It would appear that we are instantiating a new ActionListener and giving it an actionPerformed() method. We’ve succeeded in giving our button a listener without first creating a class to handle the event.

Anonymous Inner Classes

Of course we aren’t really instantiating ActionListener – it was a trick. What this does is create an anonymous inner class only in this part of our code. Check it out – when you compile your code, javac will create extra class files for our ActionListener.

For one-off buttons, using anonymous inner classes is an excellent way of reducing code bloat and improving the readability of your programs. There are drawbacks of course, which I’ll go into detail in another article, another day.