Sunday, August 17, 2008

Does your team culture encourage learning?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/does_your_team_culture_encourage_learning.htm]

In the ever-growing field of software engineering, continually learning is essential. While a lot of developers internally have the drive, they're stuck in a team that externally makes it difficult to learn. Here is a checklist of simple questions to gage how much a team encourages learning.

  • Spending money

    • Will managers buy a technical book without giving the developer a hassle? For management to spend $30 on a book, for which a developer then spends dozens of personal hours digesting and learning a whole new skill, is an incredible rate of return. If management is too short-sighted for that ("aw, can't you get it online", "did you check your local library first", "the project budget can't afford that", etc...), then your team is toast. Of course a developer could abuse this by requesting to fill an entire book shelf, so common sense applies. A book is month is very reasonable.

    • Will management provide adequate resources to explore a new task? For example, if you're investigating continual integration, you will need a spare build server.

  • Encouraging team collaboration

    • Can your team set up a wiki such that everyone can easily share trivia and knowledge?

    • Are code reviews encouraged by all the managers and influential contributors?

    • Do senior team members actively mentor junior members, or are developers too busy pounding out features to "waste" on mentoring?

  • Scheduling

    • Do most features allot at least some time for research and improvement - even 5-10%? That means if you spend a whole week plugging away at a feature, management is okay if you take at least a few hours to explore a tangent, or incrementally improve the system?

    • Microsoft, as well as many user groups, occasionally sponsor free local events. Management may not pay thousands to send you to fancy training, but will they at least let you occasionally take the day to attend a free training session?

  • Process

    • Do your processes display public results, and are those processes documented, such that anyone on the team can investigate and understand them? Or, are the processes cautiously guarded by some "builder master" guru or manager who doesn't want anyone else to see the big picture for fear that it would somehow "threaten" them?

  • Features

    • Are the interesting features shared across the team, such that everyone gets a chance to explore cool technologies, or does the architect/team-lead hog the cool features for themselves and leave the boring work to others?

    • When your team needs a research project, is it assigned internally so that your own guys get the opportunity to learn about it, or is it sold off to some external consultants, or is research forbidden altogether ("we don't have time/money to learn to do things  better")?

  • Management

    • Development requires innovation, which requires risk, which inevitably results in the occasional "failure". Does management allow developers to take a calculated risk (i.e. not belittling or embarrassing the developer when it doesn't work out)? If not, developers will be afraid to innovate, which means they're be afraid to apply what they've learned, which will reduce their incentive to learn new things.

    • Will management emphasize the total cost of ownership, which ultimately can only be reduced by continual education of the entire team? If managers only emphasize the current task ("we don't have time to do it right, we need to get this feature coded now."), and learning (even if it's for the current task) means you're not actually programming (i.e. "typing in keystrokes") at that moment, then managers will discourage developers from learning. In other words, is learning seen as a first-class task?

    • Does your promotion system emphasize career goals, which in turn emphasize some learning goal?

These things do not necessarily imply a good or bad learning environment:

  • Sending developers to expensive training - Back during the .com bubble, there was plenty of cash to send anyone to training. However, as mentioned above, there are still plenty of ways for a company to encourage learning without sending the developer to a fancy training session.

  • Asking you to handle an occasional boring task - Ultimately any engineering project will have something tedious and boring that needs to be done. This doesn't mean that the team is anti-learning. However, if every task is boring and hacked, then that's an obviously bad sign.

  • Emailing links to "best practice" articles - Any kid can email links to coding guidelines or best practices that someone else wrote, and for which it requires the discipline of other developers to actually adhere to. There's nothing brave or helpful about yet another checklist.

Thursday, August 14, 2008

Why play games instead of writing them?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_play_games_instead_of_writing_them.htm]

I've met a lot of younger kids who say they like computers, by which they mean they "like playing computer games." I've seen these kids learn just enough about networking and hardware to get their favorite game installed, and then rot their brain with thousands of hours of un-educational video games.

 

Sure, a little game playing to relax and recharge is one thing. But throwing away the formative years of your career - i.e. high school, college, and post-college - is a sad thing to do.

 

It doesn't need to be this way. Programming can be fun, perhaps as fun (or even more!) than playing a computer game. The idea is that if writing a fun program (which has a huge learning benefit) is about as enjoyable as playing a deadbeat game (with no learning benefit), then obviously it's better to budget your time for more programming.

 

So, why is solving the nth level of Game XYZ fun, but solving how to code an algorithm or UI screen not? Let's look at several reasons, and see how programming could fulfill the same fun criteria.

 

Why game-playing is fun?How programming can achieve the same result
The game is relaxing and takes less mental energy.You can pick an easy, relaxing project.
The game offers you new and exciting things to explore (new level, creature, technique, etc...).There's always new things to learn while programming, and these new things usually provide you with a marketable skill.
You can stop the game at any time.You can take a break from your pet project at any time.
The game consumes your mind, and sucks you into its world.Ditto.
You can play with your friends.You can build an open-source project with your friends (such as using shared space on CodePlex), or share your new app with friends or coworkers.
You cannot lose at the game (provided you have the sufficient cheat codes).Ok, so your program may crash and fail, but you can usually find help (such as on a forum or from a coworker), or reduce the feature scope.

 

My point is that many of the things that make game-playing fun also can make programming fun. And unlike game-playing, programming offers you tons of long-term benefits.

Wednesday, August 13, 2008

Book: Bringing Out the Best in People

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/book_bringing_out_the_best_in_people.htm]

Arguably the most critical component of a software application are the people who build it. If the team doesn't get along, or lacks the drive to learn new things, then the team will eventually fall apart, and the project will come tumbling down shortly thereafter. Therefore while technical books are important, "people" books are important too. With that in mind, I just finished reading "Bringing Out the Best in People" by Alan Loy McGinnis. It was a good, easy read. He wrote it in the mid 80's, but as human nature hasn't changed much since then, it's still very relevant.

 

He offers 12 main points, including:

  • "Expect the best from people you lead" -  I interpreted this as giving people the benefit of the doubt, and encouraging them to tackle difficult problems that bring out their best talents.

  • "Create an environment where failure is not fatal" - I've seen many ex-consultants who are terrified of failure. "One wrong mistake on this project, and I get replaced with a new contractor, so I better not screw anything up". Such fear paralyzes any normal person because you can't take any risk. But software is an innovative field, and innovation requires risk. Therefore having the schedule allow for some flexibility and giving people second chances are good things.

  • "Place a premium on collaboration" - Some management structures over-emphasize "the star". Who single-handedly wrote the most code? Who fixed the most bugs? Who built the toughest features? The problem with over-emphasizing the individual (at the expense of the team) is that it often pits the individual members against each other. Then you get team members quietly asking themselves dangerous questions like "Why should I fix your bug." Think of basketball - yes there are stars, but the coach just wants to win the game - the coach doesn't care who the star is.

There's a lot to discuss about it. In short, it's nice to balance all the technical reading with a "people" book.

Tuesday, August 12, 2008

Developer Jokes II

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/developer_jokes_ii.htm]

Last August I mentioned some developer jokes. Here are some more that I've heard from various places (I'm retelling these from memory):

 

Binary joke

"There are 10 kinds of people in this world - those who know binary and those who do not."

 

The value of knowledge

Bob had worked 30 years in the engineering department, only to retire a few months ago. As luck would have it, one of the main systems broke down, and a desperate manager eventually tracked Bob down, calling him back in. He poked around the system for 10 minutes, and then flipped a single switch, and everything started working again. As he walked out, he scribbled his fee on a sheet of paper: "Total $10,050: That's $50 for the time, and $10,000 for knowing what switch to flip."

 

Explaining technical concepts

A sharp college student was interviewing with an average technical company. The student was getting bored with the trivialness of the questions. After 20 minutes, the recruiter, looking down at the checklist, asked "So, can you tell me what is polymorphism?"

 

"No problem," the ace student replied, "that's just the ability to define multiple classes with functionally different, yet identically named methods or properties that can be used interchangeably by client code at run time."

 

"Um," replied the recruiter, a little surprised, "now can you describe that in terms a manager would understand?"

 

"Sure," responded the bored student, "it's magic."

Tuesday, August 5, 2008

The significance of two-way databinding

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_significance_of_twoway_databinding.htm]

ASP.Net came with one-way databinding, and seven years ago that was a big deal. Instead of looping through each element in an array and individually adding it to a dropdown, you could now just bind the array to the dropdown with a single line (or two) of code. This obviously simplified things.

this.MyDropdown.DataSource = myEmployeeList;

this.MyDropdown.DataBind();

However, there were still some complications. Because the Asp.Net CodeBehind still needed to reference the UI control (in this case "MyDropdown"), the CodeBehind still had references to the UI design. For example, if the designer wanted to change the control from a standard dropdown to a custom EmployeePicker, you'd need to update the CodeBehind. As a result, there was still a tight coupling between UI design and coding implementation. This is one-way databinding: the control loads it's data, but it has no way to save data when changed. Sure, you could abstract out styles to CSS, but that essentially just lets you set an adjective, we want to change the nouns.

 

Xaml improves this by offering two-way databinding.  Jesse Liberty has a good tutorial. By merely setting certain attributes, you can now also save any UI changes back to the data object. This allows all the data-binding to be done in the Xaml itself - the CodeBehind can be set up to have no knowledge of what UI controls it's data is being sent to, or modified by. Therefore, two-way databinding allows a true separation between code and design.

 

In the CodeBehind, set the UI control's DataContext:

this.LayoutRoot.DataContext = myObject;

Then, in the Xaml, you can specify the two-way binding on every control within that UI container. The "magic" is the "Mode=TwoWay" sub attribute.

This really clicked for me when I had the opportunity to attend a Rocky Lhotka CLSA presentation, where Rocky whipped up a simple UI form to demonstrate some backend code, and then had a talented UI-oriented coworker modify just the Xaml file (no touching Rocky's technical code). The app went from another list-details WinForm to looking like a Hollywood movie.

 

By allowing a true separation between UI design and coding, Xaml will make it easier for developers to specialize. Before, because everything was so tightly coupled, most developers had to learn both the UI technologies (HTML/JS/CSS...) and the backend technologies (C#, SQL...). Now, it's easier for developers to learn a niche in one tier. I think this is part of how the ever-expanding .Net world works - the overall application is better, and requires more knowledge to develop, but .Net is designed in such a way to spread that knowledge across more people, therefore still making it manageable to develop.

 

Monday, August 4, 2008

An analogy between game play and manageability

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/an_analogy_between_game_play_and_manageability.htm]

In the demanding field of software engineering, everyone wants to have technical ability. That's great, but there's more. As most problems are big enough that they require multiple people, that means that someone needs to manage these people. This means that a good employee should not just be technically able, but also manageable. It's like when playing Age Of Empires (or any real-time strategy game), imagine you have the "super unit" - i.e. a technical star - but they won't obey orders. You want them to move right, but they move left. It would drive the player insane (you could simulate this by using a older, pre-laser, mouse where the track ball gets dirty and the mouse no longer responds properly). That's what it's like to have an unmanageable employee. In fact, when judging most games, "game play", in this case the ability to manage your units, is a major factor. After all, what good is the "super unit" if you cannot control it?

Thursday, July 31, 2008

Why would my program suddenly stop working?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_would_my_program_suddenly_stop_working.htm]

Deterministic bugs are easy. When you write "ConvertCelsiusToFahrenheit", the debugging is simple. When things break, they're very repeatable, and it's easy to step through the debugger and see why. However, production code doesn't work this way. Sometimes your enterprise application will just temporarily stop working, only to resume working correctly again a little later. Why? Here's a few ideas:

  • Caching - something was cached, and the cache expired.

  • Session - the session expired

  • External dependencies - a dependent web service or database could be down

  • Rare boundary condition - perhaps your code doesn't account for certain rare input (like nulls, or not escaping special characters)

  • Concurrency - perhaps the code works great in a single thread (which is how must code is tested), but doesn't handle being run concurrently, for example one thread deadlocks, or another process locks a resource.

  • Too much load - perhaps too much load temporarily crashed something - like throwing an out of memory exception.

  • Randomness - maybe your code uses random numbers, and most of those work, but some of them don't - i.e. the code crashes when the random number is divisible by 111, or something really weird like that.

  • Incremental buildup with rounding error - perhaps every time the code is run, it produces an incremental buildup somewhere, like inserting a row in a database table. And as long as there are less than X rows, it "rounds down" and works. However, once the table has X+1 rows, it "rounds up" and something fails. This is abnormal, but certainly possible.

There is almost always some sufficient cause that causes the code to act abnormally. It helps for your app to have a good logger, such that you have clues to track down what that cause was. It also helps to have a QA environment that matches production, so that you can try to reproduce the steps yourself. Knowing that there will inevitably be production errors, it should encourage us to write good code upfront such that we take care of all the easy errors and these preventable bugs don't distract us from fixing the non-trivial ones.