Somewhere along the way, I seem to have become a senior developer. I’m not much faster at coding than I used to be, and I definitely have forgotten more language-specific syntax than I remember. The difference, if there in fact is any, seems to be in knowing the patterns and the norms, having a sense of what paths to use to solve problems and how to find one’s bearings in a new environment.
None of this is particularly complicated. So, since our community-building startup What’s Cookin’ welcomes new developers who want to get their feet wet in a real team, I thought it might be useful to write a bit of it down, as a guide for new developers on how to find their balance while jumping on board.
If you are already an experienced developer, this probably is not the essay for you – though if you want to kibbitz and add your two cents, have at it – comments welcome.
1) Ask questions usefully.
2) Choose places and names with care.
3) Exercise is Healthy
4) You Will Break Things (and how to be careful)
5) You Will Miss Deadlines (propose the simplest possible solution to solve the problem.)
6) Unblock Yourself. Find a Next Step.
7) Rapid iteration and feedback loops
8) Deal directly with stakeholders. Ask for the use case. Follow Through.
9) Keep Learning
You will get stuck. Despite reading whatever docs are available, googling the errors you run into, and doing your best to read the source and solve your own problems, you will at some point not see a clear path to moving forward in a reasonable amount of time.
(Caveat – you are never really completely stuck; but if you are having to disassemble the operating system to debug the problem, well, you may not come out of your rabbit hole in this lifetime.)
At this point, you want help. There is a right way to get help. Two key things to keep in mind are:
A) senior dev time is extremely valuable
B) whatever issue you ran into, someone else likely has – or will – too
Therefore, you want to communicate your problem in a way that peers on the team can see as well – especially other junior developers. Possibly one of them knows the solution, and if not, at least when someone helps, the answer will be visible in the shared space (most likely a slack channel).
Always include the exact error message string (so others can search on the same error), and if any URL is involved include the exact link. Summarize what you already tried. Use “` “` or ` ` quotes in slack. Do share in a channel, do not ping the channel. Wait some amount of time and then ping an individual developer if you did not get a response.
Rule of thumb: Asking the question should be more work than answering it. A lazy question will get a lazy answer.
Do not be afraid to admit if you are clueless – just make it clear you need only a clue as to how to proceed.
Where to put something and what to call it is the first choice you will generally make when doing a new bit of work. These are important choices and worth discussing.
* Check for existing work. Has someone approached this problem before? Perhaps a solution already exists, or a component that should be reused.
* Be predictable. It is more important to put something in the expected place or name it in a standard way than it is to be clever or right. Look for implicit standards and patterns in existing code.
* Name semantically. Naming conventions are how you communicate the intention of your code. Naming is also one of the Three Hard Things in programmingTM.
* Leave breadcrumbs. How will future developers find what you are creating? Should it be linked from a central wiki or doc, or mentioned in a related repo?
Code rots. Documentation rots. That is, if code is not exercised in tests and by users, other changes will occur which will eventually render it invalid. Documentation of how to do something which is separate from the code which actually does the thing, likely will become inaccurate over time as the code changes and the documentation does not.
The more code or documentation is used, the less it will rot.
Put instructions as close as possible to the object in question. Write clear and precise error messages. Create feedback paths for users to complain when things are broken.
The only way not to break anything is never to do any work. This is not recommended.
The thing to aim for is to notice as early as possible when you have broken something, preferably before you have deployed it to live users.
* Set up a local test environment with test coverage. Run tests on your changes.
* Make minimal changes to solve the problem at hand, unless refactor or new design is clearly called for
* Ensure your changes are backwards compatible. If they are not you must figure out who to notify of them.
* Test in a staging environment
* Notify anyone who may be affected by your changes.
* Be aware of what monitoring and alerting is set up. Will you know if it breaks later?
And most important:
* When things break, take responsibility immediately, tell people it is broken, and what steps you are taking to fix it.
A teammate once said the best way for a software engineer to estimate a completion date, is to make your best estimate and then multiply by three and increment the units (2 hours=>6 days)
Yet reliability is key, and estimates are necessary. The thing to do is communicate early as soon as you realize your estimate will slip, and give options for simplifying the work if you can to make it happen faster. Let your teammates/manager know if you need help to meet a deadline.
If you accept a task on our team, it implies you think you can finish it within a week. If you can’t, better not to take the task, give it back, or ask for help. At a minimum an update should be provided within a week on any active task. If the task is too big, create a subtask for yourself.
Corollary: Always propose the simplest possible solution to solve the problem.
It will often happen that you do not have a clear next step. Resolving the vagueness is an important skill. Some possibilities:
* You have not been given a task. Look thru the task tracker, see if a task is listed that you can adopt. Let people know in chat that you are available to pick up work. If inspired, make a proposal for an improvement.
* You have a task, but it is vaguely defined. Clarify the use case – what is this really going to be used for? What is the end purpose? How will you evaluate it? The first step may be to draft a design proposal. Provide something concrete and ask for feedback. Example output may be most useful for helping your end users clarify their wishes.
Having something wrong is the first step to getting something right.
* You have a task, but it seems huge. This is a frequent occurrence! Your first step is to break it up into subtasks. Don’t worry about creating all of them. Create the first one with a clear deliverable and send it to whoever asked you to do the task, or post it to the team channel, that this is how you will start.
Make decisions for yourself, but let people know what decisions you are making!
A pattern worth calling out is to speed up iteration time. Often the most valuable step in a problem is to find a way to quickly reproduce it. Set up test harnesses. If you need feedback from a person, try to set up live pairing. Share screen. Meet directly with stakeholders. Do everything you can to get direct rapid feedback to iterate on your solutions.
In order not to be blocked, you may need to decide on your own how to move forward. Do it! But let people know so they can chime in as needed. Once movement is happening it will be easier to get feedback, people pay attention to moving objects.
Start with simple sketches and text to get feedback early before investing time in detailed design and code.
Ok that was three. But the core principle is to find out who needs this thing, why they need it, and make sure it actually gets to them in the end.
Finding out what the original need is that drives a project can save huge amounts of time by implementing the minimal solution that actually solves the problem.
When you return a deliverable, think thru from the perspective of the stakeholders who will actually use it. Will it make sense to them? How will they access it? Make sure your deliverables are sent to the right recipient.
Tracking down nitty gritty problems is learning, and so is studying specific syntax. However it is useful to also keep learning at high levels. Search for resources relating to your language or environment plus “design patterns” or “best practices”. Try to understand the data models, memory management, index and search strategies affecting your problem.
The end goal: Solving the right problem in the best way in the shortest time.
Thanks for reading! Hope this is a bit useful, please add your favorite tips for new devs of all types.