Friday, December 7, 2007

On Technical Proficiency and the Gaining of Such, Pt 2

In my previous post, I began talking about how a Junior Developer might gain technical proficiency in his or her job and become a better developer. In particular, I talked about how a Junior Developer might gain technical proficiency through his or her experiences. I discussed how potent such experience can prove, though I also discussed the most common pitfall: Embarrassing and sometimes catastrophic mistakes. In part two of this series, I'm going to discuss a gentler, kinder, more roundabout method of gaining proficiency: Self education.

Self-education is just as important as experience in gaining technical proficiency, but for altogether different reasons. Firstly, you should always be learning. Period. Computer science and software development change so often and in such sweeping ways that it's easy to lose your place among all the new ways of developing, thinking about, and maintaining software. Though it would be impossible to even tread this kind of water, it is you're responsibility as a Junior Developer to always keep up with the newest methods of software development.

Self-education also keeps your mind in that software-development mindset. When you're reading articles and blogs on database relations, object-oriented design, Ajax, LINQ, or the newest iterations of whatever technology you use, that will keep your mind in the developer mindset. When you come to see problems as objects, solutions to those problems as methods that allow objects to interact with one another, and database tables as ways to save the state of those objects, then you'll find that you become a much more effective programmer. You will learn to quickly assess certain situations and be able to implement them as objects and ultimately code much more quickly. Just as the IDE and RDBMS that you use are tools that allow you to do your job, so is the methodology that you use a tool in allowing you to translate real-world problems into abstract software ideas and later into code. The better you become at this, the better programmer you will be.

Of course, there are downsides to self-education as a way to gain technical proficiency. Unfortunately, not every cool new design methodology that sounds really great on paper (or your monitor) translates very well into real-world usage. Some design concepts may be very novel and unique in their approaches, but that doesn't necessarily mean that they practical. I have recently been toying with LINQ to SQL in my spare time, and while it is certainly new and exciting, it unfortunately does not lead to much practicality, especially if you or your company focuses on the n-tier architecture. It's a great idea, Microsoft, but I think it needs another iteration or two before it's ready for prime time.

Even when you do happen across a new design method or technology that is practical or better than that which you already use, that doesn't mean that you'll actually be able to use it. There are many other restrictions placed on your available tool set other than the practicality of a new method or architecture. For instance, if you work for a company, then chances are that you use whatever methodology, technology, and best practices used there. And if you're a Junior Developer, then your chances of being able to persuade your boss into changing paradigms to a new design methodology or technology remain very small. That isn't to say that you're boss won't let you do something like that on a small side-project or in a non-mission-critical area, but more likely, he'll probably be more concerned about your becoming proficient in the technologies that the company is using so that you can more quickly become a good programmer in areas that are mission-critical. Your boss is certainly not to blame for that, as he is primarily concerned with the practicality of your skill set and the criticality of your tasks.

However, despite these limitations, I believe that self education is probably the more important of the two paths to becoming more technically proficient. Experience only teaches you of methods, practices, and schools of thought that already exist and have probably been around for a while, especially if you work for a company and are developing enterprise-level solutions that require more stability than dependence on bleeding-edge technology. Self education, however, can open your mind to realms of thinking and approaches to software development that you never would have reached on your own. Even if your boss or company would never allow such sweeping changes as whatever the latest development fad may be, you can at least adapt elements of that fad that could make your code more readable, portable, and easily-maintained. If your boss does call you on it, you can explain to him what you're doing and how it makes your code more human-readable, less error-prone, and more easily maintained. What's he going to do, tell you to change it back and make it worse? He actually may very well do that, but at least you'll have a.) tried, and b.) learned a new way of thinking in the process. What's the harm in that?

Of course, the best areas in which to try out such new things is your personal life. Working on personal projects at home is a great risk-free way to expose yourself to new and exciting forays into software development that you'd never get to do at work. This has another side-benefit of improving your performance at work, as well, since you'll be gaining your own personal experience by working on personal projects in your spare time. I'm not telling you to give up the spouse or significant other, of course, just to keep yourself afloat in this ever-changing world of software design by devoting part of your personal life to learning something new related to your field.

So there you have it: Two sure-fire ways of gaining technical proficiency examined. We've learned that experience is great, but has two very large drawbacks: 1.) You can and will make mistakes, and sometimes very costly or embarrassing ones, and 2.) You will only gain experience in the technologies and methodologies to which you are currently exposed, which can be very narrow if you work for a large company. We've also learned that self education is also very important, as it allows you to tread down paths that you never would be able to go in your professional life and will expose you to ever-expanding and exciting techniques in software development.

Saturday, December 1, 2007

On Technical Proficiency and The Gaining of Such, Pt 1

This is going to be a two-parter about how Junior Developers gain technical proficiency and the advantages and disadvantages of each method. For this part, I'll talk about gaining technical proficiency through experience. In my next post, I'll talk about gaining technical proficiency through self education.

As Junior Developers, often our number one enemy is lack of technical proficiency. Our lack of technical proficiency is often the key reason that we make mistakes, that we feel dumb, and that we aren't as productive as the more experienced programmers. These side-effects of our lack of technical proficiency directly result in our not always working on the most exciting projects or with the most cutting-edge technologies.

While at times, most Junior Developers may bristle at the idea of not being at the forefront of their companies' projects, as a Junior Developer, you must view the situation from your boss' perspective. The more important the project, the more likely the chances that your lack of technical proficiency may lead to any number of mistakes. This mistake could simply be writing bad code or could result in the loss of absolutely critical user data. With that in mind, you can see that it's more time- and cost-effective for your boss to put you on smaller, less mission-critical projects or to have you doing routine maintenance on current projects. Your boss likely hopes that through working on smaller side projects you will gain the technical proficiency needed to work on the bigger and more exciting projects.

So now you ask the very obvious question: How can I get me some of that technical proficiency?! Very simply, there are two ways to gain technical proficiency: Experience and self-education. In this article, I will discuss the advantages and disadvantages of learning through experience. Next time I'll hash out self education.

Experience arguably produces the most gains in a Junior Developer's technical proficiency, and for good reason. Experience can teach lessons that self-education cannot. Experience reveals whether or not those high-level theories you learned in college or read in other developers' blogs are truly practical and usable in the real world. Experience teaches a Junior Developer which tools work best for a certain job and how to better use those tools. Experience can even be second-hand, as talking to a senior developer can yield some of the best advice and practices that the Junior Developer has ever come across.

There exists, however, one very ugly side to experience, and probably the chief cause of instantaneous bowel-emptying: Mistakes. A Junior Developer's lack of experience will very often cause him to make mistakes. The mistakes are usually benign in nature and are expected of someone with his level of experience. For example, maybe the Junior Developer wrote inefficient code that called the database too many times, or perhaps introduced a logic flaw into a piece of code he was maintaining, or left a WHERE clause out of an UPDATE statement. These problems can easily be fixed with a little guidance (and a visit to the transaction log!).

Unfortunately, not all experience-related mistakes are fixed so easily. Many times have Junior Developers caused major problems that may have cost the company thousands or even tens of thousands of dollars. Such mistakes not only damage the company financially, but they severely damage the Junior Developer's confidence. In a perfect world, the boss would remain calm and realize that such problems result from the Junior Developer's lack of technical proficiency and experience, but in the real world, ass-chewings, finger-pointing, and even being sent home for the day are possible end-games for such serious mistakes.

The making of such mistakes can not only cost the company lots of money and seriously shake the confidence of the Junior Developer, but they put a large strain on the boss-employee relationship held between the Junior Developer and the Team Lead (or Project Manager, or whatever title is used at your company). By making such a huge mistake, the Junior Developer violates the trust of the Team Lead, since the Team Lead in essence delegates the programming jobs for which he does not have time to his developers and Junior Developers. When anyone messes up, that trust is violated, but when a Junior Developer messes up, the effects are more profound, since there's not much trust there to begin with.

The best advice I can give about gaining technical proficiency from experience consists of one central tenet: Always be able to undo whatever you're doing. Just as importantly, be sure that you know how to undo it. If you can sort of cushion yourself against your own mistakes by always knowing that you could undo your last goof-up, then you'll be able to experiment a little more freely and program with a little more peace of mind. Be weary when you begin working in an area where you're not particularly knowledgeable about how to undo your own mistakes.

There exist many other facets of experience and its effects on technical proficiency that I will visit throughout many posts, but those are the chief pros and cons, at least in my mind. Next time, I'll talk about self education, that double-edged sword that can offer great gains in technical proficiency, at least if you find some some that's actually applicable in your real-world situations.

Friday, November 30, 2007

War Stories: Bringing Down the Server With a Simple Select Statement

What follows is one of my more horrific war stories. There were many casualties, and I was almost killed in action, but my indomitable fighting spirit spurred me on. That, and I took two days off that resulted in a five-day vacation, since it fell during the week of Thanksgiving.

I was writing a SQL query that would merge users. Since users are connected to numerous tables throughout this particular database, this requires a lot of updating of different tables. Also, since the user table is the table with all the, you know, user data like UserName and UserPassword, that's the table that's queried when a user logs into the website. Easy stuff, right? Obviously, this user table is an extremely important table in the database.

Since I'm having to update all these tables with new user information and later remove old user information, I wisely decided that all of these UPDATE queries need to be wrapped in a transaction. For the uninitiated, when a group of queries is wrapped in a transaction, all of the queries function as one atomic unit. This means that if any one query in the transaction fails, all changes made up to that point in the transaction are rolled back. To the programmer and the end user, it appears as if nothing has happened. Maintaining such data integrity is absolutely imperative where I work, since we don't use test databases and instead directly query the production databases. At the end of my transaction, just before the COMMIT statement, I select from the user table to grab some pertinent information.

So I'm writing my transaction and feeling great about life. I put the transaction in a Try block and put code in the Catch block to rollback the transaction, thus guaranteeing that my transaction will behave correctly. Or so I thought.

As I was testing my shiny new transaction, it fails. No sweat, I think, my catch block just rolls everything back and we're good as gold. Then I notice that I'm receiving email notifications indicating that individuals are not able to login to the website. At the time, I don't make any connection with what I'm working on and this login problem, so I continue working.

For the next forty-five minutes, these login errors keep popping up. No one has said anything to me, nor do the errors indicate that any problems were occurring in the user table, so I continue merrily along, testing my transaction and watching it fail, but thinking nothing of the failure.

Then my boss calls me into his office. I immediately recognize the tone as the "You just seriously f__ked up tone." I walk in and he has the activity monitor pulled up, which shows a stalled transaction that's locked the user table. He asks me what I'm doing, I tell him, and he immediately lays into me, asking why on God's green earth I'm SELECTing in a transaction, and if I absolutely have to, why I'm not using WITH(NOLOCK), which keeps the table from being locked during a read. Not having known that it was possible that my transactions were not being rolled back and further not having known that my SELECT statement was locking the user table, I proceeded to put on my best deer-in-the-headlights look and stammer stupidly. He sent me back to my office and had one of my coworkers join me to explain what had happened.

He was so mad, he did not even chew me out after the initial questioning. It was kind of surreal, as up until that moment in my life, I had never felt so ashamed at not being chewed out. I had messed up that badly. I was so absolutely mortified that I wanted to go hide underneath a rock. This happened around 2 o'clock in the afternoon, and I gave serious thought to just leaving. In retrospect, I'm surprised that my boss didn't send me home. I even began to question whether or not software development was truly my thing.

So what lessons did I glean from this? Several, listed below and in no particular order:

  1. If you're selecting from a heavily-used or mission-critical table, always use WITH(NOLOCK) to keep the read from locking the table.
  2. Do not rely in SQL Server 2005's Try and Catch blocks to work correctly. I still have no idea why my Catch block was never executed. Instead, if using a transaction, you should precede it with SET XACT_ABORT ON and end it with SET XACT_ABORT OFF just after the COMMIT statement. SET ARITHABORT ON ensures that the current transaction, and only the current transaction, is rolled back if any of its contained queries fails.
  3. Use named transactions. If you don't use named transactions and they become nested, say by having a stored procedure that contains a transaction which calls another stored procedure that contains a transaction, then it's possible that either the wrong transaction will be rolled back, or none of them at all.
  4. The activity monitor is your friend! I now keep it open at all times and check it often during testing.
So that was one of my most embarrassing moments in my career. However, it did teach me a lot, and the lessons I learned about transactions will probably never be forgotten.

Thursday, November 29, 2007

The Junior Developer

This blog will be about exactly what the title says - The Junior Developer. Why The Junior Developer? Because that's what I am: A Junior Developer. I've been developing software using .NET, ASP.NET, and SQL Server 2005 for a little over a year and a half now.

And boy, it can be a rough ride sometimes.

I've had peaks so high that I couldn't see the ground. We're talking those programmer highs you get when you finally make that breakthrough towards which you've been battling for a week. We're talking the highs that come from finally developing that awesome algorithm that does exactly what you need it to do, no more, no less. We're talking that high that comes from creating that one method that answers all your business objects' problems

But we're also talking about the lowest of the valleys. We're talking bringing down the entire website by accidentally and unknowingly locking a table in a transaction that never got rolled back. We're talking forgetting to catch error's on the main login page so that no one can log in. We're talking forgetting to restart IIS on the production server after copying new files over. We're talking mistakes that could cost your company hundreds of thousands of dollars.

There's a big similarity for me in both these peaks and valleys: I find myself not caring about my salary. At the summit of the peaks, I don't care about how much I make because I'm so euphoric and in the moment that my boss could reduce my salary to $1 and I wouldn't care for at least an hour or so. During the troughs of the valleys, I'm so embarrassed, ashamed, and mortified by my own mistakes that no amount of money would make me feel better.

This blog is about the ups and downs of being The Junior Developer. This blog will offer tips for other Junior Developers, tips that I've come across either by my own research or, more often, my own experience (read: mistakes). The tips will not necessarily be coding tips: They may also be emotional, mental, or just plain old common sense in nature.

I'm starting this blog not only for myself, but for all the other Junior Developers out there that have experienced the highs and lows of being the low man with no experience. I'm starting it for every Junior Developer who needs guidance, who needs that dose of encouragement, or who's just about ready to throw in the towel.

Remember, brother (or sister!): You're not alone. I'm here leading the charge, and there's thousands of other Junior Developers who are or have been exactly where you are.