Software Development Mentor

Introduction

This page is the culmination of 20+ years software development experience, distilled into nuggets of wisdom and guidance for the up-and-coming software developer.

There is not cheating in life, but if you take in the guidance of this page (while it is in draft or when it is finished) it will help you be a step ahead of many other developers.

If you want to ask questions or discuss any points on this page, just email me at jason@jsnelders.com.

Status: Draft.
Expected Completion Date: 1 March 2019.
Last update: 13 February 2019.


General Advice

  • There’s no such thing as best practice.
    It’s just good practice in a given context.
    Likewise, there’s no such thing as a bad practice.
    Good and bad practice are:
    1) Someone’s opinion.
    2) The result of laziness and not wanting to think about hard choices.
  • Think defensively. Tools will fail you. Take a backup.
    Git can stuff up. Hard drives die. A global find-and-replace can have unintended consequences.
    For example: If you’re doing a tricky merged in Git, make sure all your local branch changes are committed and pushed. That way if the merge goes bad to you can simply blow away your local branch and pull from origin again.
  • Don’t Repeat Yourself (DRY).
    This is a good principal to apply to the whole of life, not just code.
    DRY, in the context of code, means “if you’re writing the same code multiple times in different places, create a function that can be called instead”.
    Duplicate code means more complexity and duplicate maintenance.
  • Optimise, but not before you need to.
    This is often stated as “don’t prematurely optimise”.
    Again, a good principal to apply to life.
    It’s OK to do get something working inefficiently the first time round. The idea is to get it working. In doing so you will learn things.
    No software is built right the first time. It generally takes 2 or 3 or more iterations. Add optimisation to those iterations.
  • All software must be maintained.
  • Software does not live in isolation.
  • The aim is to less code.
    Less code means less complexity, less that can go wrong, less to test, and less to maintain, (also: less work).
  • Test. Test. Test. Then test again.

Communication

  • Repeat back: Repeat back requirements to the person(s) giving them to you, in your own words. This is especially important if the language isn’t your first language (for example, Indian or Chinese is your first language, and the requirements are in English).
    This is a something I have my entire career, even as an English speaker receiving requirements from other English speakers.
    Something experience teaches you: people miss important details when giving requirements.
    Details are forgotten or not thought of. Requirements are not reviewed before delivery. Or maybe ideas or assumptions are wrong and need to be challenged.
    So repeat the requirements back as you understand them, and ask questions.
    To borrow (and slightly grammatically correct) the motto of a non-English speaking developer I work with: “Before starting any work , we must be clear with the requirements”. I couldn’t have said it better myself.
  • Repeat and ask multiple times: It’s OK to repeat back requirements multiple times. Or ask the same question multiple times.
    Sometimes details are missed the first time. And the second time.
    Or something may have changed in the meantime and you haven’t been told.
    In fact, always assume details are missed or being changed until the final product is delivered.

Programming

  • Use //TODO: Comments
    TODO comments are a powerful way of leaving reminders for yourself and telling other developers what’s happening.
    I use “Remove”, “Obsolete” and “Implement” all the time.
    Using TODOs is a quick way of leaving notes and task reminders in code without breaking your flow. Quickly stub out functions, “if” statements or blocks of code where you don’t want to get get stuck in the details right now but know you need to come back to.
    Examples might include:
    //TODO: Obsolete // Add this to obsolete code you may want to remove later.
    //TODO: Remove
    // Add this to commented code you want to remove later, after testing.
    //TODO: Implement
    // As you’re writing out function or code block placeholders.
    //TODO: Harden // If some needs more exception/validation/scenario handling (i.e. code hardening is required).
    //TODO: Bad // If some code may do bad things in edge cases.
    //TODO: Test // If some code needs better bettering.
  • Compact code is hard to read. Use white space and indentation.
    Code is read by humans. So it needs to written cleanly and clearly. White space around lines, functions, and blocks of code helps with layout and readiblity.
    In the modern age, white space costs very little (if nothing) to the compiler.
    I generally add 3-5 blank lines between functions.
    I add group related code then 2 lines between groups within functions.
    Vertical white space (blank lines) helps when needing to quickly scan code. It works well in conjunction with lots of comments too.
    Indentation is horizontal white space. Again, it helps with scanning code and identifying blocks of related code (e.g. start and end of “if” statements and functions).
    Tabs vs Spaces is an age old arguments. Don’t waste time on it. I recommend tabs because if you’re using a decent, modern IDE (as you should) then you can set tab sizes to whatever you want.
    The key thing to remember is: your code will be read by other people. And other people read differently to you (the may be dyslexic, had poor vision), so be respectful of that.
  • Use descriptive variable/function/class names.
  • Don’t get fancy or compact with code. Write long and clear.
    Code is meant to be read and understood by humans.
    Usually the person reading it is not you, so fancy code makes it harder for them and takes more time.
    Even if you are reading it again, chances are you will need also help understanding it in 2 months time.
    Compilers don’t care how fancy your code is, but humans do.
    Spread you code over multiple lines, use descriptive variables, write long-hand if you can, add comments.
    The key: do everything you can to help other developers understand your code.
  • Comment. Comment. Comments – Write lots of comments!
    Anyone who says “get rid of that comment” should be kicked out of the industry! (I’m serious)
    Along with TODOs, comments are one of the greatest tools in a software developer’s kit.
    The do 2 things:
    1) Help other developers – this is the main reason to write comments.
    2) Add a bit of documentation directly to the code.
    Comments should be added everywhere – to classes, functions, enumerations, variables, “if” statement branches, blocks of code – everywhere!
    The thing to understand about comments: comments should “tell the story” of what the code is “meant to do”.
    Even something as simple as if(person.Age > 18) should have a comment “People over 18 are allowed to drink” within the branch of the if statement. This shows the business requirements behind the code, but it also means if you accidentally write if(person.Age < 18) and a bug is raised, whoever reads the code later can see there’s a difference between the implemented code and the intended outcome.
    I sometimes even write a blank “else” in an “if” statement, even if nothing happens, with a simple comment like “nothing happens here” just so everyone if wasn’t accidentally forgotten. It also helps my subconsciously think through all use cases of the code.
  • CSS (Cascading Style Sheets): Start with a global class, in an external stylesheet, that can be used everywhere.
    Then override using CSS specificity only as needed.
    But always in a CSS file.
    Use inline styles with caution.
  • Use a good IDE (Integrated Development Environment).
    IDEs are a developer’s best friend. They don’t really need to be fancy to give you a productivity boost, but if you’re writing software in a basic text editor, you’re doing it wrong.
    Look for an IDE with features like: global find and replace; syntax colouring; intellisense (if you can get it); language-specific error checking; setting tab width.

Security

  • Assume all input data cannot be trusted.
    This includes data coming from users, APIs and databases.
    Assume it is dirty.
    Assume it has problems.
    Review and validate.
    Always!

 

Working With Git

  • Learn and understand the core actions
    • Creating repositories
    • Branching
    • Adding/removing files for a commit
    • Commenting
    • Committing
    • Pushing
    • Pulling
    • Merging
    • Viewing file diffs
    • Viewing file change history
    • Submitting pull requests
    • Completing pull requests
    • Stashing/un-stashing
  • Understand branching strategies
  • Regularly merge from parent branches
  • Commit and push to origin before merging
    I recommend committing and pushing all local work to origin before you merge.
    If something badly screws up with the merge then you can delete your local branch, pull from origin again, and retry the merge. This has saved me a number of times in the past.
  • Create backup branches locally

Learning

 

Thinking About Software

  • All software has entropy.
    It will change and decay over time.
    Why? Because software does not live in isolation.
    It relies on infrastructure, platforms, tools, and dependencies that will change, which in turn cause the software itself to change.

 

From University to a Job

  • Where’s what you need to boost your changes of getting a software development job:
    • Know how to use Git.
      • Learn commands for: creating repositories, branching, adding/removing files for a commit, commenting, committing, pushing, pulling, merging, diffing, viewing file change history, submitting pull requests, completing pull requests, stashing and unstashing.
      • Learn about branching strategies. There are many out there. Consider what you think is a good strategy.
      • Learn about merge conflicts and strategies for avoiding/resolving them.
      • Learn the git command-line, but you can also use GUI tools (they can be much easier and quicker for visualising large projects and handling merge conflicts).
    • Have a sample project in a public repository (e.g. GitHub or Bitbucket).
      It can be big or small, but you should be passionate about it.
      Use this to demonstrate you’re code, that you are proactive, and talk about it in interviews.
      This is your demonstration of experience.
      Include supporting files and assets in the repo.
    • Start learning about:
      • DevOps
      • Application Security
      • Visual Design & UX/Usability (particularly if you want to work on consumer-facing products)
    • Find one language and learn it well. You will need to learn multiple languages in your career, but start with one you can focus on.