Tuesday, May 12, 2009

Automated Code Governance

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

There are lots of ways for a tech-lead to encourage standardization. However, any policy that requires manual enforcement will continually be facing an uphill battle. The problem with the human enforcer is that:

  1. Enforcing policy is seen as being the "bad guy", and no-one wants to always be the bad guy
  2. The human will not have time - they'll be pulled onto other features
  3. The human will be accused of "ivory tower" antics that just slows down real work
  4. The human cannot possibly monitor everyone's code every day

The optimal way is to have an automated build policy as part of your continuous integration. This policy could check for many objective metrics, such as (DISCLAIMER: I haven't personally implemented all of these yet - it's just a brainstorm based on various research):

  • Code Coverage - Enforces developers to write unit tests by demanding that the tests provide X code coverage.
  • Code metrics (like NDepend) - Runs static metrics like LineCount (discourages large methods that have multiple responsibilities) and cyclomatic code complexity (including checks for dependencies, which is often then #1 culprit that prevents testability).
  • Code duplication (like Simian) - Encourages refactoring by checking for chunks of duplicate code. Ideally, this covers not just C#, but all languages like HTML, JS, and SQL.
  • Static code analysis (like FxCop) - Runs static rules to check for bad or risky code, kind of like compiler warnings on steroids.
  • Stored Procedure scans - Creates a test database, and runs all the stored procs to check their query execution plan for performance bottlenecks (like table or index scans), or too many dependencies.

While policies sound cool, in the trenches, many devs view them as just a nuisance that slows down "real" work. Here are some problems to anticipate:

  • Devs don't want to do it - it's not fun to write high-quality code.
  • Devs complaining that they don't have time
  • Management pulling the rug out from under you (they don't have time, or they don't want to be the "bad" guy)
  • Makes build take too long

Given these types of problems, here are ideas to minimize any riots as you try to roll these out.

  • Set up policy first - without it failing the build yet, so everyone can see results for a few weeks.
  • Ensure that people can run all policy checks locally first, and verify that they pass locally.
  • Create an exclude list so any developer can register exceptions.
  • Grandfather all existing code by using this exclude list.
  • Minimize the scope of what is checked (start with just 1 core assembly, and gradually expand to others).
  • Roll out 1 policy at a time.
  • Ramp up your build servers. Consider a distributed build, such as using CruiseControl's project trigger feature.

Monday, May 11, 2009

Avoiding unnecessary server work in ASP.Net

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

One of the best ways to increase performance in ASP.Net pages is to not do any unnecessary server-side work. For example, every postback and callback will re-trigger the entire Page's server life cycle - rerunning OnInit, OnLoad, OnPreRender, etc... However, a server-side action only require a fraction of the original code to run - for example clicking a button may not require you to repopulate all dropdowns.

ConceptExampleDetails
Is PostbackClicking an ASP.Net button postbacks the pagethis.IsPostBack
Is CallbackA JavaScript triggers an ASP.Net 2.0 callbackthis.IsCallback
Is RedirectingA method has called Response.Redirect, but there is still heavy processing (that is now unnecessary) that will still be called.Response.IsRequestBeingRedirected
Is Ajax update panel postbackA button within an Ajax update panel has been clicked, but don't redo server work outside of that update panelpublic static bool IsPartialPostback(System.Web.UI.Page p)
{
return ((System.Web.UI.ScriptManager.GetCurrent(p) != null)
&& (System.Web.UI.ScriptManager.GetCurrent(p).IsInAsyncPostBack))
}
Is Button clickUser clicks exit button - no need to repopulate dropdownsRequest["__EVENTTARGET"] //indicates which event (like a button) triggered the postback.

 

Sunday, May 10, 2009

Yes-no questions that a non-technical recruiter can ask during an interview

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

When interviewing, many companies first filter developers through HR (such as for online resume screening or a phone call). The irony is that they want a technical star, but screen all candidates through non-technical HR folk. Sometimes people in such situations, pressed for time, resort to quick yes-no questions. The naive approach is to just ask "rate yourself on 1-10", or "do you have over X years experience?" While I think the best type of interview is one where technical people can ask technical questions (or even write pseudo-code on the whiteboard), not every developer gets that opportunity. So if for whatever reason, the recruiter is limited to only yes-no questions, consider these kind of questions:

  1. Do you program in your spare time? --> programming in your spare time implies that you enjoy programming, which implies that you're motivated and good at it.
  2. Do you have any Microsoft Certifications? --> implies basic Microsoft-specific education
  3. Do you have an engineering or CS degree? --> implies a basic general education
  4. Have you ever lead a team of over 3 people? --> implies basic leadership abilities.
  5. Have you ever programmed an application over X thousand lines-of-code? --> big apps will provide scalability and process problems that small apps never will.
  6. Are you an active member of any professional groups? --> implies motivation
  7. Have you ever been published (magazine, online journal, book)? --> implies good communication
  8. Do you have your own website or blog? --> implies personal motivation and innovation
  9. Do you contribute to any open-source projects? --> implies hands-on coding and working with others
  10. Since college, have you read more than three technical books? --> implies continual, pro-active education, as opposed to just re-actively reading scattered blog posts.

This is only a partial list, but you get the idea. Many developers can have "X years experience", yet never do a single thing on this list. This list focuses on what you have done, not how long you've sat in front of a computer.

Thursday, May 7, 2009

Technical Debt is like a steep hill, not a brick wall

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

Overtime, bad software decisions (design, coding, process) get compounded, like interest on a loan, and effectively presents the team with a "technical debt" that yearns to be repaid. This debt weighs down the system, making it harder and harder to make changes or add new features. One way to measure technical debt is by lines of code that require maintenance. Therefore you can reduce debt by reducing lines of code (codeGen, refactor, automate, buy instead of build, etc...).

For example, a developer may copy and paste duplicate code a hundred times (like in HTML or SQL), or create thousands of lines of tedious plumbing code, or create an army of brittle JavaScript files, or write an entire app with no code coverage. Many of the best practices out there are designed to explicitly reduce technical debt.

One thing to note is that technical debt is like a steep hill that can go infinitely high. You can go fast bicycling on a flat road, but as that road turns into a steep hill that gets gradually steeper, you slow down. In software terms, because code may have been copied to 10 different places, making a single change requires 10 separate updates - so it takes longer.

I don't think technical debt is like a brick wall - where suddenly at a specific point you're blocked and you simply cannot go further. And that's part of the problem. As long as you're moving, albeit slower and slower, it's seductive to think that you can still keep making "enough" progress so you don't need to change yet. The stubborn leader can just keep pushing on: "longer hours, more developers..." There are two choices to make: keep going forward, or turn around. However, if you were to hit that brick wall, then it forces you to stop and reevaluate. It's easier in the sense that you now only have one choice - you must "turn around".

Monday, May 4, 2009

Cool Tool - NDepend for automated code metrics

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

Given human nature, and all the tedious things that go into coding, the coding standards that survive are usually the ones that you can automate with some external tool.

Code Metrics is one such type of governance. Two of the most popular metrics are line count and cyclomatic complexity. Perhaps the best tool on the market to assist with these (and much more) is NDepend.

For example, say you want to prevent developers from writing huge methods, or huge files. You could use the command line for NDepend to check for method-line-count, and then fail any check-in that doesn't meet this policy - just like you could fail a check-in that doesn't compile or breaks a unit test.

Cyclomatic code complexity is another one - this (to simplify it) measures the number of dependencies. The more dependencies, the harder to instantiate something in a test harness, so this is actually a big deal. You could reduce dependencies by leveraging interfaces and abstract classes, using injections, or the like (whole books are written about this).

This is just the tip of the iceberg. NDepend has dozens of these types of metrics.

Initially I tried to use Visual Studio's "code metrics" feature, but for some reason I cannot fathom, you cannot run it from the command line - which of course makes it useless for an automated build (which is the whole point). At least VS code coverage had undocumented techniques to work around this.

I realize there are open-source options for basic file line count, but I personally haven't come across any that can effectively do the other metrics like method line count and cyclomatic complexity.

Bottom line - if you're trying to enforce automated governance through your build, consider checking out NDepend. Yes, there's a license fee, but if it saves you even 10 hours by preventing issues and bad design, then it's paid for itself. Also, being aware of these types of metrics is the kind of thing that helps take a developer to the next level.

[Disclaimer - I haven't fully implemented this myself yet, it's still in a research phase, and I'm just sharing my findings]

Sunday, May 3, 2009

Chicago Code Camp sessions and agenda are up

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

The Chicago Code Camp (at CLC in Grays Lake, IL), which will be May 30 (Saturday), has the speakers, sessions, and agenda up.

It's all all-star cast, including several MVPs.

There's a huge variety, including TDD everything (even TDD for JavaScript and the iPhone!), UI, backend, many non-.Net platforms, and much more!

Wednesday, April 29, 2009

Management decisions for good developer cost-benefit ratios

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

I've often seen development groups (or their managers) dismiss a good idea with "we can't afford it." The irony is that the group is already "affording" other expenses - developer salaries, MSDN licenses, hardware, and office space - so the question really becomes not "are there funds", but rather "what is the best way to spend our funds". There are at least three common examples where, for some reason, many managers shun the best cost-benefit ratio.

Problem 1: "We cannot afford a star developer - let's get two average developers instead."

The irony is that one star developer is far more profitable than two average developers. The star will build complex things that a dozen average developers will never be able to dream of. The star will write more solid code that spares you costly production errors. The star will solve the same problems faster by leveraging advanced techniques (like code generation, refactoring, or just elegant solutions). So, if you're creating a team of more than 10 developers, exchanging the bottom two spots for 1 star is a good investment. ThoughtWorks, a world-class consulting firm, does a good job of demonstrating the profitability of this business model.

Problem 2: "We cannot afford that tool - just do it another way instead."

Say you spend somewhere between $70K-$120K on an average developer (not just salary, but benefits, payroll taxes, etc...).  Let's use $100K for easy numbers. At 50 work-weeks (assume 2 weeks of vacation), that's $2000 a week to pay for a developer - i.e. $50 an hour. So, a $50 tool that saves your developer one hour a year is a break-even investment.

Now about the "power tools" out there - like CodeSmith (for code generation), or ReSharper (for refactoring), or Simian (for detecting code duplication), or NDepend (for code metrics) - say it's a few hundred per tool (i.e. less than 0.5% of your developer labor cost). However, a tool like CodeSmith fundamentally changes the rules of the game, and can save a development team hundreds of hours. Sure, you can try to find open-source alternatives to each of these, and if you find something that fills the niche you need - great. A similar problem applies to hardware (where's there's not an open-source alternative)- for example when management "saves" $200 by not providing sufficient memory on a laptop, such that every hour of coding is sluggish due to a slow machine.

For many groups, a manager refusing to fund this kind of software engineering "equipment" (sounds classier than just "tools"), is like telling a construction worker to dig a trench - but we can't afford a $20 shovel, so use this spoon instead. Again, if a company is creating a 5 person development team, better to have only four people, but funded with the right equipment, then five developers who need to dig with spoons.

Problem 3: "We cannot afford that book - just see if you can figure it out from free, online tutorials."

Of course everyone knows that continuing education is vital in software engineering. In the manager's perfect world, they have a team of self-motivated developers who study on their own time, paying for their own materials, and learning at their own expense. And then, the manager (who has contributed nothing) gets to benefit from having all these learned developers. While yes, a developer is ultimately responsible for their own learning and career, a wise manager would realize that the company has a huge vested interest in the developer's learning, and would hence do things to encourage that learning.

Perhaps the most basic thing a manager could do is to have the company pay for a book that the developer is motivated to read. A book costs between $30 and $50 dollars. If a developer spends 20 of their own hours (on nights and weekends) over a month reading and absorbing that book, such that they can now profit the company with a new skill, this is a no-brainer. It could cost management thousands to send a developer to training (plus the days off work). It could cost management additional thousands to fix mistakes resulting from the developer not knowing that profitable technology. A book is cheaper, can be re-read by other developers, and is often read off the clock. Money speaks, so if management can't even encourage a motivated developer's learning with a $30 every other month, they're effectively telling developers that management doesn't value learning.