Skip to content

Instantly share code, notes, and snippets.

@m-ammar
Forked from rondy/Effective_Engineer.md
Created January 4, 2018 06:08
Show Gist options
  • Save m-ammar/13235ffe062cd909bf13cd16fd70a90e to your computer and use it in GitHub Desktop.
Save m-ammar/13235ffe062cd909bf13cd16fd70a90e to your computer and use it in GitHub Desktop.

Effective Engineer - Notes

What's an Effective Engineer?

  • They are the people who get things done. Effective Engineers produce results.

Adopt the Right Mindsets

Focus on High Leverage Activities

  • Leverage = Impact Produced / Time Invested
  • Use Leverage as Your Yardstick for Effectiveness
  • 80% of the impact comes from 20% of the work.
  • Focus on high leverage and not just easy wins.

Optimize for Learning

  • Change jobs if you have to.
  • Optimizing for learning is high leverage.
  • Adopt a growth mindset.
    • Talk to people. Become good at telling stories. It gets better with time.
    • Those with a growth mindset believe that they can cultivate and grow their intelligence and skills through effort.
    • Own your story.
  • Invest in the rate of learning
    • Learning compounds. Compounding leads to exponential growth. Earlier the compounding starts, the better.
    • Working on unchallenging tasks is a huge opportunity cost. You missed out on compounded learning.
    • Prioritize learning over profitability.
    • Invest your time in activities with the highest learning rate.
  • Seek Work Environments Conducive to Learning
    • Fast Growth: Companies where #problems >> #resources. Opportunity to choose high impact work.
    • Make sure you are working on high priority projects.
    • Openness: Look for culture with curiosity, where everyone is encouraged to ask questions.
    • Fast Paced.
    • People smarter than you.
    • Autonomy: Freedom to choose what to work on. Smaller companies => More autonomy.
  • While on Job
    • Make a daily habit of acquiring new skills.
    • Read code written by brilliant engineers.
    • Jump fearlessly into code you don't know.
    • Always be learning. Invest in skills that are in high demand.
    • Read Books. Attend Conferences.
    • Build and maintain strong relationships.

Prioritize Regularly

  • Opportunity cost of working on wrong ideas can set back growth by years.
  • Prioritize tasks based on ROI.
  • Regular prioritization is high leverage activity.
  • On TODO Lists:
    • Maintain a 'single' todo lists where all tasks are listed.
    • Don't try to remember stuff. Brain is bad at remembering. It's rather good at processing.
  • Ask yourself regularly: Is this the most important thing I should be working on?
  • Focus on what directly produces value.
  • Learn to say no.
  • Focus on the important and non-urgent.
  • Find ways to get into flow. “A state of effortless concentration so deep that they lose their sense of time, of themselves, of their problems.”
  • When possible, preserve larger blocks of focused time in your schedule.
  • Limit the amount of Work in Progress.
    • Cost of context switching is high.
  • Prioritizing is difficult.
  • Prioritization is high leverage. It has huge impact on your ability to get right things done.

Invest in Iteration Speed

  • Continuous Deployment is high leverage.
    • Will save a lot of time in manual deployment of code. They are the people who get things done. Effective Engineers produce results.
  • Move fast to learn fast.
    • Move fast and break things.
    • Moving fast enables us to build more things and learn at faster rate.
  • Invest in time saving tools.
    • If you have to do something more than twice, write a tool the third time.
    • Tools are multipliers that allow your to scale your impact beyond the confines of a day.
    • Faster tools get used more often.
    • Faster tools can enable new workflows that previously weren't possible.
    • Productivity skyrockets with tools.
    • Time saving property of tools also scale with team adoption.
  • Shorten your debugging and validation Loops.
    • Extra time spent in optimizing debugging workflow can help you fix annoying bugs with less headache.
    • Debugging is hard. It's time consuming. Upfront investments to shorten debugging loops are worth it.
  • High test coverage to reduce build and site breakages.
  • Fast unit tests to encourage people to run them.
  • Fast and incremental compiles and reloads to reduce development time.
  • Master you programming environment.
    • One editor. One high level language. Shell. Keyboard > Mouse. Automate manual workflows. Use interactive shell. Make running specific tests easy.
  • Faster you can iterate, faster you can learn.

Measure what you want to Improve

  • Use metric to drive progress.
    • If you can't measure it, you can't improve it.
    • Good metric.
      • Helps you focus on right things.
      • Drives forward progress.
      • Helps you guard against future regressions.
      • Performance ratcheting: Any change should strictly improve the metric.
      • Bad metric can lead to unwanted behavior.
      • Examples:
        • #hours worked < productivity.
        • click through rates < long click through rates.
    • Metric you choose influences your decisions and behavior.
    • Look for metric that, when optimized, maximizes impact for the team.
    • Actionable metric - Whose movement can be casually explained by team's effort.
    • Responsive metric - Updates quickly to give back feedback whether a given change was =ve or -ive.
    • Choosing a metric is high leverage.
    • Dedicate time to pick right metric.
  • Instrument everything to understand what's going on.
    • Measure anything, measure everything.
    • Graphite, statsd. A single line of code lets you define a new counter or timer on the fly.
    • Measuring goals you want to achieve is high leverage.
  • Internalize useful numbers.
    • Knowledge of useful numbers provide a valuable shortcut for knowing where to invest efforts to maximize gains.
    • Need upfront work. Need not be accurate, ballpark idea suffices.
    • Knowing useful numbers enables you to do back of the envelope calculations to quickly estimate the performance properties of a design without actually building it.
    • Internalizing useful number help you spot anomalies. Be skeptical about data integrity.
  • Log data liberally.
  • Build tools to iterate on data accuracy sooner.
  • Examine data sooner.
  • When numbers look off, dig in to it sooner.

✔️ Measure your progress. Carefully choose your top-level metric. Instrument your system. Know your numbers. Prioritize data integrity.

Validate your ideas early and often.

  • Not validating early leads to wasted efforts.
  • Don't delay get feedback.
  • Find low effort ways to validate work.
  • Power of small batches. Helps you avoid making a big mistake by stopping the flow.
  • Approach problem iteratively.
  • No large implementations.
  • Working solo? Be wary. Be extra vocal and get feedback.

Improve project estimation skills.

  • Beware of mythical man month. Communication overhead is significant.
  • Reduce risk early.
  • Rewrite projects - almost always fail.
  • Additional hours hurt productivity. Causes burnout.
  • Do the riskiest task first.
  • Allow buffer room for the unknown.

Balance Quality with Pragmatism

  • High code quality. Code readability.
  • Establish sustainable code review process.
  • Code reviews help:
    • Catch bugs and design problems early.
    • Sharing working knowledge of the codebase.
    • Increases long term agility. Easier to understand, quicker to modify.

Manage complexity through Abstraction

  • Example: MapReduce.
  • Right abstractions make huge difference.
  • “Pick the right ones, and programming will flow naturally from design; modules will have small and simple interfaces; and new functionality will more likely fit in without extensive reorganization,”
  • “Pick the wrong ones, and programming will be a series of nasty surprises: interfaces will become baroque and clumsy as they are forced to accommodate unanticipated interactions, and even the simplest of changes will be hard to make.”
  • The right abstraction can increase engineering productivity by an order of magnitude.
  • Simple abstractions avoid interweaving multiple concepts, so that you can reason about them independently rather than being forced to consider them together.
  • Designing good abstractions take work.
  • An abstraction's usage and popularity provides a reasonable proxy for its quality.

Automate Testing

  • Unit test cases and some integration testing provide a scalable way of managing growing codebase.
  • A suite of extensive and automated tests can reduce overall error rates by validating the quality and by safeguarding against regressions.
  • Tests also allow engineers to make changes, especially large refactorings, with significantly higher confidence.
  • Despite its benefits, it can be difficult to foster a culture of automated testing.
  • Focus on high leverage tests.
  • Writing more tests, creating a virtuous feedback cycle and saving more development time.

Repay Technical Debt

  • Technical debt refers to all the deferred work that’s necessary to improve the health and quality of the codebase and that would slow us down if left unaddressed.
  • Accumulating technical debt is fine as far as it is repaid within time.
  • Refactor often.

Reduce Operational Complexity

  • Keep no. of technologies low. Don’t sway towards shiny new technologies.
  • Every additional technology you add is is guaranteed to go wrong eventually. Will need your time.
  • Do the simple thing first.
  • Embrace operational simplicity.
  • The first solution that comes to mind is generally complex. Don't stop. Keep peeling off the layers of onion.
  • Simplify the architecture to reduce their operational burden.
  • “What’s the simplest solution that can get the job done while also reducing our future operational burden?”
  • Discipline to focus on simplicity is high leverage.

Fail Fast

  • Fail immediately and visibly.
  • Doesn’t necessarily mean crashing your programs for users.
  • fail-fast to surface issues immediately.
  • Failing fast is high leverage as it saves debugging time.

Relentlessly Automate

  • Automating mechanics is good.
  • Automating decision making - no.
  • Hone your ability to respond and recover quickly.
    • Leverage recovering quickly > Leverage preventing failures.
  • “script for success,” practice failure scenarios, and work on our ability to recover quickly.
  • Make batch process idempotent
  • Make processes retryable, i.e., not leaving any global state.

Invest in your team's Growth

  • Invest in onboarding.
  • The higher you climb up the engineering ladder, the more your effectiveness will be measured not by your individual contributions but by your impact on the people around you.
  • "You’re a staff engineer if you’re making a whole team better than it would be otherwise. You’re a principal engineer if you’re making the whole company better than it would be otherwise. And you’re distinguished if you’re improving the industry.” - Focus primarily on making everyone around you succeed.
  • Your career depends on your team's success.
  • Make hiring everyone's responsibility.
  • Shared ownership of code.
    • Keep bus factor more than one.
    • Shared ownership removes isolated silos of information.
  • Build collective wisdom through post mortems.
  • Invest in automated testing.
    • Automated test cases lead to higher confidence when refactoring.
    • Write test cases when the code is fresh in mind.
    • Don’t be dogmatic about 100% code coverage.
    • Value of tests increases over time and cost to write goes down.
  • Hire the best.
  • Surround yourself with great advisors

☀️ “Leverage is the lens through which effective engineers view their activities. ” ☀️

10 Books to read:

  • Peopleware Productive projects and Teams. Amazon. My Summary.
  • Team Geek: A Software Developer’s Guide to Working Well with Others. (Debugging Teams) Amazon. My Summary.
  • High Output Management
  • Getting Things Done: The Art of Stress-Free Productivity
  • The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich
  • The 7 Habits of Highly Effective People: Powerful Lessons in Personal Change
  • Conscious Business: How to Build Value Through Values
  • Your Brain at Work
  • Flow: The Psychology of Optimal Experience
  • Succeed: How We Can Reach Our Goals

Blogs:

Recommended Blogs To Follow:

  • http://www.theeffectiveengineer.com/ - The Effective Engineer is my personal blog, where I write about engineering habits, productivity tips, leadership, and culture.
  • http://www.kalzumeus.com/ - Patrick McKenzie runs his own software business and has written many excellent long-form articles on career advice, consulting, SEO, and software sales.
  • http://katemats.com/ - Kate Matsudaira, who has worked at large companies like Microsoft and Amazon as well as at startups, shares advice about tech, leadership, and life on her blog.
  • http://randsinrepose.com/ - Michael Lopp has worked for many years in leadership positions at Netscape, Apple, Palantir, and Pinterest, and writes about tech life and engineering management.
  • http://softwareleadweekly.com/ - Oren Ellenbogen curates a high-quality weekly newsletter on engineering leadership and culture.
  • http://calnewport.com/ - Cal Newport, an assistant professor of computer science at Georgetown, focuses on evidence-based advice for building a successful and fulfilling life.
  • http://www.joelonsoftware.com/ - Joel Spolsky, the co-founder of Stack Exchange, provides all sorts of programming pearls of wisdom on his blog.
  • http://martinfowler.com/ - Martin Fowler, author of the book Refactoring, writes about how to maximize the productivity of software teams and provides detailed write-ups of common programming patterns.
  • http://pgbovine.net/ - Philip Guo, a computer science professor, has written extensively and openly about his graduate school and work experiences.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment