What defines a professional software engineer?
There isn’t a simple answer to that question, but after reading several books on the subject I identified some tips that I have found useful.
Which ones do you like? Which ones don’t you like? What do you think is still missing in this list?
- Before figuring out how to do something, ask why this needs to be done in first place. Challenge assumptions. Try to find an easier solution.
- Before committing to large projects, validate that they will work. Invested time in the validation will save wasted effort if the project is not realistic.
- Do not rewrite from scratch if a system can be improved incrementally.
- Define clear goals. It will show if you fall behind and you need to update your estimate.
- Incur technical debt when it’s necessary to meet a deadline. Then gradually pay it off.
- Stick to the proven tools that are right for the job. Trendy technologies might be fun to explore, but they lack support, and expertise, and often require reinventing a wheel.
- Say no to any unrealistic requests when the stakes are at their highest. Instead, suggest more feasible solutions, such as reducing scope.
- Regularly measure your progress against goals. Estimate using three fact-based dates: best case, normal case, and worst case.
- Ensure there is no ambiguity in requirements.
- Do not overwork. It is inefficient and decreases productivity. Overwork leads to mistakes that need to be corrected later.
- Focus on the 20 percent of tasks that deliver 80 percent of the value (80/20 principle).
- Question every activity to determine if it can be done faster, produce more value, or if there is another activity that delivers a higher impact.
- Measure effectiveness by the number of new subscriptions, new users, new features, sales, or improved core business metrics -- not by lines of code, long hours, meetings, reports, or completed tasks.
- Proactively schedule time to deal with distractions so that they won’t interrupt your get-stuff-done time. Do not try to eliminate all distractions as it won’t help build trust.
- When you are in a hole - stop digging. Have the courage to back out from a solution that isn’t working out, even though you’ve invested a lot of time into it.
- Do not agree to work overtime!
- Ship products that users love, launch features that customers pay for, build tools that boost productivity, deploy systems that help companies scale.
- Study existing code in your company, study all material available internally, master your programming languages, send your code review to the harshest critics, and jump fearlessly into code you don’t know.
- Define effective ways for others to deliver results.
- Make the organization’s goals your goals. Earn trust and respect through demonstration of ability.
- Improve your writing: use Twitter, add documentation, blog.
- Lead by demonstrating expertise and professionalism. Guide everyone to the common goal.
- Make everyone around you succeed.
- Do not succumb to the pressure of a deadline or an authority. You are paid for your expertise. Your company relies on you to act professionally.
- If you run a team, understand issues that the team exists to solve.
- Familiarize yourself with the following:
- Design patterns
- Design principles - SOLID, Component
- Methods - XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design
- Disciplines - TDD, OOP, Structured programming, CI, Pair programming
- Artifacts - UML, DFD, Structure charts, Petri nets, State transition, flowcharts, decision tables
- Balance your code reviews. Rigorous process impedes velocity. Lack of code reviews allows bugs to slip through.
- Abstract APIs in a way that makes them easy to learn, easy to use, hard to misuse, easy to extend, and appropriate to the audience.
- Automate unit tests to save time in the long run.
- Invest time to produce an elegant solution which will benefit the system in the long run. The initial solution is generally more complex, fragile, and hard to understand.
- Build systems that fail fast and visibly. It makes them robust, easier to fix, and less buggy.
- Automate mechanics (repetitive tasks) first. Then automate decision making.
- Approach coding problems as follows:
- Understand the problem.
- Write a failing test.
- Solve the problem as fast as you can.
- Tidy up your code and make sure the test passes.
- Commit changes.
- Do not over-engineer. Add flexibility, abstraction, and layers only when they are absolutely necessary, and not because they would be “cool” to have. Over-engineered code is hard to comprehend, test, change, and maintain.
- Establish coding guides and conventions but do not enforce them with rigor.
- “Premature optimization is the root of all evil.”
- Build your application in a way that it can be monitored and supported.
- Do not refactor for potential future benefit - “You ain’t gonna need it.”
- Do not refactor just to “clean it up.” Refactor when you know that it will have an economical effect.
- Do not break discipline (even under pressure) as it will slow you down. The code must be clean and tested.
- Correct the design early-on when it is moving in an unmaintainable direction. Ignoring this can drive the system into a swamp from which it may never escape.
- Ask the 5 Whys.
- Monitor and instrument your systems.