Makings of a Great Software Engineer

Many software developers call themselves “Senior Software Engineer” or “Software Architect” but are they really? Recently I’ve meet a few people who claim to be more than they were:

An upper level manager claimed to be a “Software Architect.” On a project that was responsible for distributing millions dollars. He argued, during the design phase, against a ledger. Even after discussing GAAP compliance and ledger implementations in other accounting software, he would not budge his position.

A “Senior .Net Software Engineer” claimed the best way to send an error message via services was throwing exceptions:


public bool IsValidLogin(string username, string password)
{
    if (UserLogic.IsValid(username, password))
    {
        return true;
    }

     throw new Exception("Invalid credentials were provided.");
}

Imagine consuming this method — expecting a “false” but receiving an exception.

Determining someone’s level is somewhat subjective. Here is what I look for: First, do you understand the pro and cons of your solution? Second, do you know the alternatives and can you compare and contrast the two solutions. And third, can you explain the architecture, performance, scalability and maintenance implications surrounding your solution?

4 tenets of a great software engineer

  1. Knowing your limitations
  2. Continuous Learning
  3. Experience
  4. Understand the business

Knowing your limitations

Knowing when to saying “I don’t know” is the most important asset a developer can possess. Without it you will never seek more knowledge, you will never ask for help and you will never master your profession.

Are you reaching the edge of your skill set? Can you learn the needed skills and complete the project in the expected timeframe? Are you out of your league? Knowing the correct answer is the art.

Continuous learning

New processes or methods are created daily. If you are not appraised and adding them to your skill set, your career is dying. One study suggests that in the software industry, if your skill set is two years behind the curve, it is obsolete. If this is you, you’d better consider a different career; maybe teaching would your cup of tea.

Google is your friend. Know it, love it, and use it. It is the single most used source to find answers. More than likely someone’s already solved your problem.

Find your niche and master it. There are many learning resources:, from podcasts to blogs, from user groups to getting a mentor. This is the information age; you can learn anything you want. If nothing else you can connect with the people who share your passion.

Experience

Experience is tough. Many employers and recruiting agencies key on experience. You can be disqualified solely on the years listed on your resume.

Software is a craft and its artisans are Software Engineers. We tailor each solution to its problem.

Experience will partly determine the success of the software. An under experienced engineer can craft the best solution and fail.

Failed software projects cost companies millions of dollars and can doom a company.

The best software engineers are the ones who have an insatiable thirst for crafting software. They augment their experience by continuous learning.

Understanding the business

As one manager told me “Marketing’s job is to spend money.” Clearly this manager doesn’t grasp the concept or purpose of marketing.

Understand the value of a solution to the business. Know the problem domain and how the software fills the gap.

Software must ship. Sometimes it’s to fulfill maintenance contracts, other times it’s to meet shareholder’s expectations. This means sometimes corners are going to be cut. Accept it, live with it and develop other day.

An Overview of Branching and Versioning

Sometimes the process of Source Control, Branching and Versioning is taken for granted. It’s not until you get into concurrent development where the weaknesses of your process become apparent. Below is a process I’ve used in the past and continue to use at my current company. It’s saved my bacon on many occasions.

Trunk

Trunk is always the most current development. By the most current development it means Trunk is the next code branch/ feature set to be released. Once the code as been released, it is versioned and branched to the branches folder and new development is continues in Trunk.

Branches

Branches are made in two cases.

The first scenario is a previous release. Code is branched from Trunk into the Branches folder after a release. New development continues on the next version in Trunk. Keeping the current production code base in a branch allows changes to be made to production in the event of a bug.
If a bug is found in production, the branch with the production code is modified and re-released to production. The change is then merged back to trunk, assuming the same issue is in trunk.

Example:

A product’s first version is released. The source is immediately branched from Trunk to Branches as a subfolder named 1.0.0. A month into a two month development cycle a bug is discovered in production. Since we have the source code of production in Branches\1.0.0 we load that source, make the necessary changes and redeploy the code to Production. We then create a new branch from the 1.0.0 folder and name it 1.0.1 and save it to the Branches folder. If the production fix needs to be merged to Trunk we either do it manually or with Visual Studio’s merge tool.

The second scenario for branching is multiple release dates. Trunk is always the nearest release date. The ONLY reason you would branch from trunk for multiple release dates is because of concurrent development. Most product roadmaps have features for multiple versions into the future. If the work can be done in serial, then there is NO reason to branch. Sometimes making deadlines forces development to begin in the previous development cycle and if these changes cannot go out in the next release (because of completeness, security, performance, testing…etc) then you must branch the code. The key to successful parallel development is to keep the branches together as long as possible, before creating a branch. The shorter the time a branch run parallel with another the less they diverge and the easier the merge process.

Versioning

Versioning is very important. It disambiguates features between release dates. Since release dates inheritably change numbers are used to indicate a feature sets.

The purpose for the “Trunk” label is with some products the versioning label is controlled by marketing.  Once the product is released and the version number is cemented then we can label it. This happens when we branch the release.

Typically version numbers look like this: 1.4.3.1434. The first position is the major version of the product. The second position is the minor version. The third number is the build number. And last is the changeset number or sometimes referred to as a revision number.

The last number is the most important of the version number. It lets retrieve the code exactly as it was when it was built.

Example:

We have a product that was released a 1 year ago. In that time we have released 3 more versions. We no longer maintain the code and have since removed it from the branches folder.  A customer calls in with a serious problem. It turns out that they have discovered a serious security issue. We have to release a fix immediately. We look in source control. We deleted that branch 6 months ago. How do we know where to find the code and make the fix? This is where the changeset number comes in. The client sends us a copy of his product; we look at the version on the assemblies and see the last position has 928 as the changeset.  From TFS we are able to retrieve the source at changeset 928. We make the change and release a fix to the client.

Could not load type ‘System.Security.SecuritySafeCriticalAttribute’ from assembly ‘mscorlib’

Could not load type ‘System.Security.SecuritySafeCriticalAttribute’ from assembly ‘mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′.

A cause for the above error is invalid XAML. I nested an unsupported element in a ListBox and got the above compile error.

Your Development Cycle

I’ve been a part of many software projects. Some big… others small, none of those projects ever had any concern on the development cycle time — The time it takes from the moment you press Visual Studio’s play button, to the time you can interact with your project.

On this new gig, it literally takes 5 minutes from when Visual Studio begins to build until you can interact with the site (it’s a web project). What the fuck? How the hell can any work get done?

So what’s the deal you ask? There are many reasons on this project: Massive classes, butt loads of Javascript, web service latency, recompilation… The list go on.

It’s all traced back to bad architecture. No one on staff had the experience to design/architect the company’s new flagship product. Management wasn’t savvy enough to see the experience gap.
Now the company is paying out the ass for any development because it takes so long to develop on this project. We all know that developers get paid for their time not their progress.

The whole point of this post is look at the development dependencies. Do you need VM’s or any special environments?

Development is only one slice of the pie, consider the other disciplines: QA, initial deployment, upgrade scenarios… etc

Tools(programs) in the Toolbox

Software is Not Easy to Write

If software was easy to write, Microsoft would be the only software company in the world, but it’s hard to write. Solid software is composed of three components: good tools, great people and refined processes. Most companies lack process and and will continue to refine process until its death. Think about this: Apple and Microsoft have been writing software for over a quarter of a century and they still release buggy products.