...and Make You More Valuable and Productive to Potential Employers
Imagine you are either searching for a job or looking for a career change.
Think about the company you'd like to work for - whether it be a start-up, a midsize company, a multi-national, etc.
Now stop; you're going about your job search all wrong.
Instead, put yourself in the position of the hiring manager who is reviewing a stack of resumes. S/he doesn't know you or care about you (yet). S/he cares about the needs of the company. The only interest s/he has in you is whether you are the right person to fill that position, which means that, by definition, you need to be the candidate that will address the company's needs.
Technologies change, so no one programming language will keep you employed indefinitely, but many skills are evergreen. Highlighting these skills, in addition to having the core technical competency, such as Java, SQL, or HTML5, will greatly increase your success rate by differentiating you from other candidates.
Review the following list, assess your level of expertise, and think about how to introduce them in a natural way to your business communication. Be sure to touch on the relevant ones on your resume and your cover letter, and bring them up in the interview. If you don't have any of these skills, obtain them. Note: I am not advising you to say, "I use abstraction, so please hire me." Instead, you should address the business strength built atop the technical skill. More about this in the conclusion to this blog post.
1. Understand the relationship between the software development cycle and the company's business
Understanding the software development life cycle's (SDLC) relationship to the employer's sales cycle and business model is critical. If you understand the entire SDLC and the company's sales cycle and business model, you can make much more intelligent choices about how to allocate your time and attention. Without that information, you are likely to risk missing important deadlines, not understand how/when to prioritize features, and waste dev cycles.
For example, if the company sells to the educational market, perhaps any software demos that aren't completed by May will have to be delayed until September when school is back in session. Every business is going to have seasonal tradeshows that are key to sales.
You also need to consider how your employer gets paid by its customers. For example, if you are in the online advertising business, the primary client deliverable is a report showing how many ads were served and to whom. If you can't report ad views accurately, then the company won't get paid and repeat business will dry up.
So you need to learn to prioritize features that are important to the company's business. The easiest way to do this is to ask your boss and people in sales/marketing, “What is the most important thing I can do from a software standpoint to affect the business's bottom line?''
2. Version Control
If I could ask a software developer candidate only one question, it would be "Tell me about your favorite version control system and why you prefer it over other options." If they don't have an answer, I would consider it disqualifying.
If you are not using subversion (svn), git, or a similar source control (version control) system, you are not a competent developer, and need to learn how to use one immediately. Period. Without version control, you have no way to collaborate, track history, revert to prior versions, manage multiple versions, refactor with confidence, or fix bugs with confidence. I'll cover more details in a future post.
3. Unit Testing
Unit testing is a long and detailed topic, which I can only touch on here. Unit testing and test-driven development (TDD) are an important way to define what software is supposed to do. In TDD, software is ready to be released, by definition, when the software passes all tests. Using unit tests allows you to make changes to complex systems while reliably knowing whether you've added the new feature successfully or accidentally broke something. Again, I'll cover unit testing and TDD in a future post in more detail.
4. Automation with Jenkins, Maven, and/or Ant or similar and Continuous Integration system
If you are manually building and deploying your software, you are likely making many errors, or wasting time, or not scaling your team. As a best practice, you should have a server running, say, Jenkins, that rebuilds the software after any changes. This can/should be integrated with version control and unit tests.
5. Understanding Software Architecture and Design Patterns
The ability to architect a project is critical to its successful completion. You wouldn't think of building a house without blue-prints, and yet people undertake complex software without any plan. You should understand how the different modules relate, where code can be reused, what components are common. And, of course, be familiar with common Design Patterns. Much more to come on this and code re-use in future blog posts.
6. Reading and Writing Documentation (Wiki, etc.)
If you can't read documentation, I don't want you on my development team. Learn how to google and read both official documentation and unofficial blogs/comments. If you can write documentation, you are infinitely more valuable. If your project isn't using a wiki, set one up. All the things you struggle with during the first week should be written down. This may include where important systems are (network drives, svn repositories, databases, utilities, installers), team contact information, or the best place to get take-out.
The arguments for/against documentation are long and sordid. I'll cover those in another blog post.
7. Understand Scalability and Repeatability
Know that every meaningful thing you do will have to be repeated in the future (See "Automation...and Continuous Integration" above).
Any meaningful piece of software will have multiple users or customers. So if a process can't be scaled or repeated, then you are probably doing something wrong. For example, if your web site fails with more than 100 concurrent users, you obviously haven't architected it properly.
Similarly, if you set up your Dev server, chances are you'll need to replicate the environment immediately for the QA server, Staging server, Production server, etc.
The same principle applies to developer set-up, customer support, etc., so consider how best to address these issues (documentation, training, scripts, etc.)
8. Estimation (time and money) and Scheduling
Know how to build lead time into the software development cycle. I have never worked at a company where deadlines weren't important, and I've never worked at a company where people were good at estimation and scheduling.
This is a long discussion summarized by “Whatever your time estimate, multiply it by 5, even after taking this rule into account.”
The truth is that most meaningful software is complex and largely unknown to the stakeholders when making estimates. Things regularly take five (5) times longer than anticipated because no on thought ahead as to the many cases that needed to be handled. This unanticipated issue could be something as simple as, “What should the software do when the user runs out of disk space?” to, “How should the software behave if the internet connection is dropped while performing a critical operation?”
This is another huge topic, which I'll cover in more depth in the future.
9. Know when (not) to Optimize
Your software shouldn't suck. It shouldn't suck CPU or other system resources, and it shouldn't suck up the user's time. That said, not everything needs to be optimized. For example, if you are streaming a 15 GB video, optimizing 3K worth of text downloading isn't going to meaningfully impact the user experience. Some people over-optimize too early. I've seen start-ups optimize for billions of transactions per day only to find they can't garner any customers or traffic. I've seen other products “perfected” before ever getting to market. (See "Shipping is a Feature,")
10. Agile Development
Agile development is a long topic that I'll cover in a future post.
Suffice to say that everything you've been doing your whole life is wrong, including how you've probably been doing agile development. In a properly functioning agile environment, there is a noticeable presence of unit tests, communication between dev/QA/biz people, user stories (aka appropriate level of specification), transparency, developer cross-training, and a shipping piece of software that functions well.
In a dysfunctional environment, there are blown schedules, unclear product direction, disjointed feature sets, buggy software, and various developers mumbling to themselves in the corner.
Refactoring is the ability to rewrite the internal functions of a module without affecting the external behavior. For example, if you refactor an “export” feature, it might have the same inputs and outputs, but operate 10x faster. The first rule of refactoring is something you would find in the Hippocratic Oath: “First, do no harm.” (Primum non nocere).
You should also understand how to, say, refactor a function to accept additional optional arguments without having to change (and without adversely affecting) any existing code that used the function prior to refactoring. This is another huge topic to be discussed in future blog posts. (See also "Unit Testing," "Using Abstraction," and "Know how to define an API...")
You must understand both the concepts and execution of migration.
For example, how are you going to migrate customers from version 1 to version 2? How are you going to migrate changes from the Dev environment to the QA environment? How are you going to migrate a code base from one technology to another?
This topic deserves at least one blog post of its own, which it shall receive in the future.
13. Know how to define an API and know how to use other APIs
You should to be able to separate your work from other people's (i.e. decoupling). Or, perhaps, you need to create a toolkit for other developers (either internal or external) Often, the best way to do that is to create an API.
For example, if I was creating a video player, it should expose “hooks” for the common operations, such as loading, playing, and pausing the video. A good developer should know when and how to create and expose a public API.
Conversely, a good developer should be comfortable/fluent in reading the documentation of someone else's API and using it to achieve a goal.
See also "Architecture" and "Refactoring" above, and see "Abstraction" below.
14. Programming Reusable code (usually Object-Oriented)
If you have fifty popup dialog boxes in your product, how many different components should you write to implement them?
The answer is probably one or two, max. Yet, I have walked into countless software projects where the developers did not create and reuse components. A software project should have less code if done right, and it should be more maintainable.
Here is a good litmus test...If I asked you to change the style and width of every button in the application, how long would it take? 1 minute? An hour? A week? A month? A year?
15. Have a tech network on which you can rely
Your value increases exponentially if you can find answers quickly by relying on colleagues and/or bring them into your current place of business. Be part of other developers' network, and make them part of yours.
16. Ticketing or Workflow system, such as Jira
You must be fluent in at least one ticketing or bug-tracking piece of software, such as Jira. There are many such systems. Understand how to benefit from one and use one daily. Learn how to be an administrator, and configure dashboards, reports, etc., to maximize its utility.
Litmus test - Excel or a shared Google Doc is not a bug-tracking system.
17. Know “enough” about hardware
If you are a software expert, you need not be a hardware expert and vice-versa, but don't be an ignorant jerk. You should know when something can/should be solved by additional hardware (i.e., adding memory, a RAID backup, a faster network connection) and when it should be solved by some software solution, such as caching.
18. Know “enough” about other people's software tools and technology
19. Know “enough” about the full-stack
A good developer will understand everything (at least superficially) from the front-end to the middle tier to the back-end. For example, if the user has to enter an email address, what sort of validation should be performed by the UI, what should be handled by the middle tier, and what should be handled by the back-end?
You need not be an expert in all aspects, but you need to understand enough to know when to say “No”. For example, if you are a front-end developer, and they ask you to store the user's password in plain text on the front-end, you should say, “no,” and know why you are saying no.
How do you gain such knowledge? By working with other qualified developers, asking questions, reading, listening, attending user group meetings, etc.
20. Know that Shipping is a Feature
Nothing is more frustrating to developers than being “piled on,” and then being blamed for the software delivery being late (i.e. feature creep, endless revisions to UI).
Nothing is more frustrating to everyone else than having to hound the developer to ask when the software will be ready.
Here are the magic words to solve this problem....Whenever anyone gives you a new requirement as a developer, state this loudly and clearly:
“This is a new, unanticipated feature that will adversely impact the original schedule. We need to adjust the delivery schedule, allocate more resources to the project, or remove some existing features and deprioritize them until the next version. Which of these three approaches do you prefer?”
If you say nothing, the person giving you the new requirement will assume the schedule will be on track even after adding the new feature and will blame you when that is not true.
Blanket statements such as “Any new feature raised will inevitably cause the schedule to slip or features to be dropped” are useless at best.
You must re-iterate the earlier statement every time that a new feature is requested. (Better yet, use Agile development). Another generic approach is to say, “That is a great request for version n,” where version n is at least +1 greater than the current version. You can cite a +3 higher version number in a matter-of-fact way, such as “That is a great request for version 4, but, for now, I'm focused on shipping version 1.”
21. Using Abstraction
"Abstraction" is the ability to create a “layer” of code that insulates the user from some underlying particulars. (Here, I am not discussing the formal concept of an abstract class in OOP).
Abstraction enables development of multiple modules to be decoupled.
For example, suppose I have implemented all my UI code to interact with an Oracle database. And then one day, I find out that the back-end developer has switched to a Microsoft DB. If I can't handle that change rapidly and easily, then I am a douche-bag unworthy of calling myself as developer.
In a good design, I shouldn't have programmed anything that is Oracle-specific, except for a small abstraction layer. And I should be able to easily swap it out for a Microsoft-specific abstraction layer, and everything should “just work.” The same principle applies to the theoretical video-player API discussed above. This is another huge topic that I'll address in a future post.
22. Clean up compiler warning and error messages
If I had five minutes to examine someone's code and wanted to judge how well it was written, I would use one single metric...and that is the number of compilation warnings/errors. A well-written project should have zero compilation warnings and zero compilation errors.
23. Know when (not) to Roll Your Own
The most frustrating developers are often senior coders who insist on re-inventing the wheel and writing everything from scratch (see defining/using an API). If you are not using other libraries and APIs, you are wasting your time and your employer's money. For example, there is a Java library that will export to Excel. If you are writing your own Excel export, you are a probably a douche-bag with an oversized ego or an undersized ability to google.
That said, don't be a foolish slave to what others have done in the past, and don't think you are a skilled programmer because you know how to cut-n-paste from a google search. Sometimes you do need to roll your own. Often the best compromise is an open source library that you can use as the base but then patch/extend as needed for your particular situation.
Well, we've covered a lot of technical topics in this discussion.
The key question is how you can relate this to a non-technical interviewer.
The answer is really simple...just translate it into something they care about such as money, time, flexibility, etc.
Here is a sample conversation:
Interviewer: "Please tell me how you think your current experience is relevant to this position"
You: "Well, can you tell me what you feel is the biggest gap in the current team or problem you are looking to solve?"
Interviewer: "Well, our biggest problem has been scalability."
You: <Insert your ingenious answer here, touching on the relevant technical topics above, such as...> "I find that the biggest obstacle to scalability is an over-reliance on the middle tier and front-end to do processing that could best be handled by a high-speed database or caching mechanism on the back end. Although my specialty is front-end architecture, I have extensive experience working with developers across the full-stack. I'm sure that if I spoke with them about the bottlenecks you're experiencing, we could come up with a solution that took best advantage of each tier's strengths."
Interviewer: "That's way too technical for me. I'd like you to come back for a second interview with the back-end and middle-tier teams"
You: "Sure thing. I just meant to say that there are a lot of factors that impact scalability. I understand how all the system components can be optimized to get you the biggest bang for the buck. That is, my goal is not just to make a scalable application. My goal is to understand the both the business needs and technical problems, assess the time requirements and benefits of each approach, and work with the other engineers to design and implement a solution that will give us the biggest benefit in the shortest time while keeping the schedule on track."
Interviewer: "Sounds great. And I understood it too!"
You: "Are there any other major areas I can speak to before I leave?"
Interviewer: "Our other major problem is managing multiple versions of the software for multiple customers. It is a huge headache."
You: "I find in most organizations, that version management problems stem from several factors. Let me ask you, do you use a version control system, and have you put in place a migration procedure?"
Interviewer: "Maybe I should consider you for the technical lead. I need people who can think and not just program."
You: "I'm happy to discuss whatever role you feel can best leverage my skills to fill the company's most urgent needs."
Please check out the ever-growing library of other blog posts on the right-hand side. Oh so fulfilling but with zero calories!