Author: Pete

Business of Software

Management Vs Leadership

Leadership, from http://www.thepracticeofleadership.net/wp-content/uploads/2008/09/image2.pngThis is a topic that has come up several times in my life. I have a Type-A personality and I like to excel and I like to be a leader. The problem is that a few times in my career that has landed me in a management position.

I have actually been slightly surprised to find that so much has already been written on this topic. Not because I thought that I had some original idea, it was that I was actually surprised that I didn’t know any of this literature existed until I actively went looking for it. More people in business need to understand this distinction between a manager and a leader.

My definition of “Management Position” means that some portion of the job is to write reviews, handle HR issues, balance departmental budgets, alot raises, and answer to someone about the productivity of your charges individually and your department as a whole.

Good managers who do all of this well are hard to find. Unfortunately, too many management positions are manned by people who were the best at whatever their department was responsible for doing. Often, the individual only took the job because it was the only decent way to get a raise and not because they had a passion to improve things through administration.

This is extremely unfortunate. What this company has just done is remove the person who is likely their most productive individual and put them in a position (VERY LIKELY without proper training) that Peter Principle’s them.

As I alluded to earlier, I am not speaking from the sidelines, but as one who was in the game. I wanted to make more money and I like to be a leader, so when a position opened up to be a supervisor at a place where I used to work, I leapt at it. I was one of the most (if not the most) productive worker in the building and one who didn’t shy away from doing what was right so I got the job.

That began my problems. My manager was removed from his position shortly afterward and I was named interim manager – a position that lasted for three months. My style of management was to “get in there and do the work”. If someone was falling behind, I didn’t coach them up… I bailed them out. If we had a big work day ahead, I came in early and got things started and prepared (or even done) for everyone else instead of trying to plan a schedule for others to help. That may sound great or heroic, but the problem was that a) I wasn’t doing anyone any favors and b) Pete don’t scale. This worked for one building and 20 employees, but if our workload or staff increased, I couldn’t bail everyone out at once. If someone quit one of the “higher responsibility” positions below me, no one had been trained up to replace them. I was blowing it, but I had no idea.

Fortunately, I did not get the permanent management position. They were prepared to give it to me, but another manager from Dallas, TX was looking to transfer and company policy gave him first dibs at the job. They apologized to me and thanked me for my efforts being both manager and supervisor for three months. The truth is that they did me a huge favor. The man who came in was a M A N A G E R.

He knew how to delegate. He knew how to schedule. He knew how to train. He knew how to discipline. The man was skilled at his craft and I began to see how I had been failing. I learned a lot about the right way to be a manager. At the same time, it also made me see that I didn’t want to be a manager though I liked being a leader.

I love setting an example. I love sharing my knowledge with others and setting a precedent, but I don’t like disciplining them if they fail to learn or improve. I love performing technical interviews for positions and giving input for hiring decisions, but I hate negotiating salary, benefits, and schedules. I love when things get busy and that means that I can be super productive while attending less meetings (that my manager has to attend in my stead). I don’t like playing politics to get my department what it needs, I like to occasionally rely on the fact that it is easier to ask forgiveness than permission. I definitely don’t like to play the game where you have to make other managers of other departments or divisions feel like they were involved in the decision so they can feel useful. I’d much rather hear the facts, decide the course, and take my troops into battle.

It seems that I have a very definite idea of what a manager does and I’ve now written much more about that portion than I had originally intended, but it feels good to get it out. What is unique about a manager is that you can (or should) only have one per spot and they can only exist in certain conditions. However, a leader can exist anywhere in your organization. You can have a leader in the receptionist’s chair, the custodial team, the accounting division, or in your auditing department. He (gender neutral from here on out) can be a software architect, a lead developer, junior developer, business analyst, or QA guy. I’m not even creating a dichotomy that says that managers can’t be leaders, too. You can have managers and executives that are leaders, too (in fact, I *pray* that you do!).

What matters is that he has a vision, acts on it and causes others to follow him to act on that vision. In finding other literature on this topic, I came across these two quotes which best sum up what I’ve been trying to say:

“The manager’s job is to plan, organize and coordinate. The leader’s job is to inspire and motivate.” (WSJ)

“Managers have subordinates. Leaders have followers.” (Changing Minds)

I hope that this is some food for thought for other Type-A’s out there as to maybe how you can best use your energies depending on what portions of the above got you excited. Not everyone can be *the* leader though, and I will be writing very soon about the importance of learning how to follow.

Code Optimization

Asp.Net Request Collections

Today on Twitter, Sahil Malik asked the question “Is there any reason ever to use Request.QueryString over Request.Params?” (link – for as long as it persists on Twitter).

For QueryString itself, there is practically no reason not to use the less specific collection, as QueryString is always checked first. That means that there is a small performance hit in Request.Params as it will check all collections regardless and not one in just calling Request, as it returns the first one it finds.

If you are trying to get at the Forms, Cookies, or ServerVariables collections, there is a performance hit (albeit small) no matter which way you turn. (Information on the happenings inside the .Net Framework are available on this Hanselman post from a few years ago.

There is an issue, however, if you want to access any of the other collections by using either Request[] or Request.Params[]. And really, this is the code smell that I was worried about when responding to Sahil earlier today. Let’s make an example page here. I made this using Asp.Net WebForms (to hopefully have the widest base of understanding).

Here is the meat of the .aspx page.

    <form id="form1" runat="server">
    <div>
        <asp:Button runat="server" Text="Submit" OnClick="submitButton_Click" ID="submitButton" />
    </div>
    <asp:Panel runat="server" Visible="false" ID="adminPanel">
    You shouldn't see me unless you are an admin.
    </asp:Panel>
    </form>

Here is the code behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Params
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Cookies.Add(new HttpCookie("IsAdmin", "false"));
        }

        protected void submitButton_Click(object sender, EventArgs e)
        {
            var value = Request["IsAdmin"];

            if (Convert.ToBoolean(value))
            {
                adminPanel.Visible = true;
            }
            else
            {
                Response.Write("You aren't an admin");
            }
        }
    }
}

The initial page load.

When we click the button, the cookie value is checked and since it is false, we get the sad news that we aren’t an admin.

After the first click.

Okay, let’s now assume that someone is curious if you are using simple cookie checks, so they look inside Firefox to see what the cookies are on your site.

Our site's cookie.

Now, let me take a chance that the operator of this site is being sloppy and is using Request[] instead of calling the value from the cookie collection explicitly. I’ll add ?IsAdmin=true onto the querystring to mirror the cookie and then click the button. Since the QueryString collection is checked first, I’ll be overriding the cookie in this instance.

Here is our result
Our site has now been compromised.

Well, that’s not good. What if we actually just check the cookie value instead of being lazy?

        protected void submitButton_Click(object sender, EventArgs e)
        {
            var value = Request.Cookies["IsAdmin"].Value;

            if (Convert.ToBoolean(value))
            {
                adminPanel.Visible = true;
            }
            else
            {
                Response.Write("You aren't an admin");
            }
        }

Now when I try the QueryString hack, the page is safe.
Crisis averted.

This doesn’t solve all of the problems with this page, though. I’m not pushing this off as some airtight secure solution. What I’m hoping to point out is that coding hard and even though we are given certain shortcuts, you really have to understand the ramifications of your code before throwing it out in the wild.

Mentoring

Extracurricular Learning

Being a lifelong learner, I believe that what I call “Extracurricular Learning” is very important. I define that as any learning that you do outside of your job or school either for fun or to better yourself due to your own drive or passion. Maybe you like to use books, or screencasts, or conferences, but you actively make learning your own responsibility.

Some developers that I know or have run across are really into JIT (just-in-time) learning. They fly by the seat of their pants and, as Jeff Atwood puts it, “page fault” in knowledge. I am by no means against learning things as you go along. If you don’t do that, you are probably a pretty terrible developer. However, I think that if you don’t do some preparation in advance, you won’t be as good at “page faulting” your knowledge as you could be.

Let’s imagine that I’m working in Ruby for the first time. I may google ruby loop or something to figure the syntax of how to do a loop. Or, let’s say I need to do some task X. What I’m likely to do as a .Net programmer is to think of how I’d do it in C# and then google for the way to do X-C#-Thing in Ruby.

What would be better is if I had immersed myself in this technology ahead of time. I don’t mean become an expert before you begin, I am talking about doing due diligence before getting involved. If I have read Why’s Poignant Guide to Ruby and watched a few TekPub videos about Ruby and attended a few Columbus Ruby Brigade meetings, then I would have a very broad overview of how to “do” Ruby. And while I wouldn’t be an expert, it would make my google-fu so much better because my searches could be targeted toward getting me the *right* information.

As I’m getting more and more into Asp.Net MVC 2 for a project at work, I find the “leg work” that I did watching the TekPub videos and reading blogs to be invaluable. If I hadn’t done the Extracurricular Learning, I probably would have attempted a lot of WebForms inspired nonsense instead of finding out about how much “magic” is available to me via the built-in framework. Much like Rails, I can get Asp.Net MVC to do a lot of work for me (especially when combined with jQuery) if I just know how to rely on the scaffolding/convention over configuration inherent in the product.

I’m not wrong on this. If you want to be a great developer, you need to be involved in Extracurricular Learning. If you aren’t, you will stagnate and be guilty of “writing FORTRAN in any language”.

Training

TekPub

Almost two years ago, in a rant titled Y Kant Developers Read?, I lamented the fact that I’m finding that less and less of my peers are reading books to gain knowledge. In the last two years, that has gotten even worse. Several programmer’s magazines/journal publishers have gone bankrupt and the book publishing industry is in the crapper. Programmers are either getting information from blogs, user groups, or conferences. Unfortunately, I fear that for the majority of programmers none of that is true. Interviewing programmers, I’ve found that most of them truly can’t code FizzBuzz or a singleton or any other fairly simple problem that I put in front of them.

Entering into the programmer learning void recently have been screencasts. I’ve long been a fan of DimeCasts (Link Removed) as a way to get introduced to a lot of different topics. I learned about (read: finally understood) Dependency Injection / Inversion of Control from DimeCasts and I think they are good people. Additionally, one way that a lot of people learned about ASP.Net MVC was from Rob Conery’s screencasts building the MVC storefront on ASP.Net (apparently – according to Rob – they’ve since been moved).

TekPub Logo
Enter TekPub. Rob Conery and James Avery started a company to produce high quality screencasts to teach programmers about topics like NHibernate with Ayende, Git, jQuery, ASP.Net MVC, Ruby on Rails, Linux, LINQ, and more. I talked my boss into buying me a year’s subscription and I am EXTREMELY pleased with how he spent the money 😉 They offer streaming video as well as downloads in standard and iPhone format. I’ve watched probably at least 15 screencasts so far and I have learned a LOT. I keep several videos on my phone and whenever I have spare time, I watch a few minutes.

Steve Sanderson’s MVC 2 screencasts are exceptionally money. I wish I had the words to explain the kinds of lights of understanding that went off in my head after watching these videos. They alone are worth the price of admission. But, they aren’t alone… I got a lot out of Justin Etheredge’s LINQ series as well as Rob’s “Build Your Own Blog” stuff. If your employer has any kind of training budget, you should get them to drop the $200.00 yearly subscription fee for you. Neither of you will regret it. In fact, even if they don’t, you should truly consider investing the $200.00 in your own future.

Code Tips

Row_Number() Part Two

Last Time, we looked at ROW_NUMBER() and saw a little of how it works and how we could use it to remove duplicates. Another one of my favorite uses for ROW_NUMBER() is to get only one row from a one-to-many join. I’ve had situations at work where I need to return one row per Person, but each person had several addresses, several injury codes, and several contacts (people working their case).

In many of those cases, there is nothing to indicate which one of those rows should receive precidence over the others. One might just select from those tables and then take just the MIN() of the primary key, grouping by all other fields, but that makes for very messy and hard to maintain code in my opinion. ROW_NUMBER() gives us a much easier way to handle this problem.

Examine this sql script that gives us a Person Table and a PersonAddress table. One person can have many addresses, but there is no way in the schema to give precidence to one of the addresses over any of the others.

USE tempdb
GO

CREATE TABLE Person (PersonId INT IDENTITY(1,1) PRIMARY KEY, Name VARCHAR(50))
GO

INSERT Person ([Name])
SELECT 'Bill'
UNION
SELECT 'Bob'
UNION
SELECT 'Carl'
UNION
SELECT 'Sue'
UNION
SELECT 'Cleo'
UNION
SELECT 'Nick'
UNION
SELECT 'Thomas'
UNION
SELECT 'Jeydro'
UNION
SELECT 'Ronald'
UNION
SELECT 'Jamie'
UNION
SELECT 'Colleen'
UNION
SELECT 'Denise'
UNION
SELECT 'Phil'
UNION
SELECT 'Jim'
UNION
SELECT 'Jack'
UNION
SELECT 'Kathleen'
GO

CREATE TABLE PersonAddress (PersonAddressId INT IDENTITY(1,1) PRIMARY KEY, PersonId INT, [Address] VARCHAR(100))
GO

INSERT PersonAddress (PersonId, [Address]) 
SELECT PersonId, CONVERT(VARCHAR, PersonId * 123) + ' ' + UPPER(REVERSE([Name])) + ' ST.'
FROM Person
ORDER BY PersonId DESC
GO

INSERT PersonAddress (PersonId, [Address]) 
SELECT PersonId, CONVERT(VARCHAR, PersonId * 321) + ' SQL DR.'
FROM Person
WHERE PersonId BETWEEN 3 AND 9
GO

SELECT p.PersonId, p.[Name], pa.[Address]
FROM Person p
INNER JOIN PersonAddress pa
ON p.PersonId = pa.PersonId
ORDER BY p.PersonId
GO

DROP TABLE Person 
GO
DROP TABLE PersonAddress
GO

Here is a sample of the results:
One to Many Addresses

Using a similar trick to what we used last time to find unique records, we can alter our select statement so that we only return one address per person. If we change our select statement to this

; WITH Addresses
AS 
(
	SELECT p.PersonId, p.[Name], pa.[Address], ROW_NUMBER() OVER (PARTITION BY p.PersonId ORDER BY p.PersonId ASC) AS RowNum  
	FROM Person p
	INNER JOIN PersonAddress pa
	ON p.PersonId = pa.PersonId
)
SELECT PersonId, [Name], [Address], RowNum
FROM Addresses
GO

We get the following results:
One to Many Addresses With Row Numbers

You can see now that all we have to do is limit the result where the RowNum is equal to one and we have something that we can use (the CTE) in further joins or in reports to ensure that we don’t introduce duplicates to our query.

; WITH Addresses
AS 
(
	SELECT p.PersonId, p.[Name], pa.[Address], ROW_NUMBER() OVER (PARTITION BY p.PersonId ORDER BY p.PersonId ASC) AS RowNum  
	FROM Person p
	INNER JOIN PersonAddress pa
	ON p.PersonId = pa.PersonId
)
SELECT PersonId, [Name], [Address]
FROM Addresses
WHERE RowNum = 1
GO

Our results:
One to One Addresses Thanks to RowNumber