Michael

corp-drone

These are the sentences that I highlighted/copy-pasted when reading the textbook Software Engineering at Google.

You will likely feel the notes are scattered with lack of context, but thats ok, if one doesn't make sense its probably fine to skip.

I think its practically useful to know about these ideas if you're a software engineer.

But, also much of it can be applied in other domains and personal life.


Human costs are not the only finite resource that needs to scale. Just as software itself needs to scale well with traditional resources such as compute, memory, storage and bandwidth, The development of that software also needs to scale, both in terms of human time involvement and the compute resources that power your development workflow. The most precious asset of a software organization—the codebase itself—also needs to scale

When we are a 10 times larger software organization: Did we add 10 times more work/latency with which our sample engineer needs to keep up? Does the amount of work our engineers must perform grow as a function of the size of the organization?

We’ve also learned that having a dedicated group of experts scales better than asking for more maintenance effort from every user.

We’ve found that expertise and shared communication forums offer great value as an organization scales.

New Experts Grow: Knowledge is viral, experts are carriers, and there’s a lot to be said for the value of clearing away the common stumbling blocks for your engineers

Whenever it is efficient to do so, we should be able to explain our work when deciding between the general costs for two engineering options

even when there isn’t data there might still be evidence, precedent, and argument. Making good engineering decisions is all about weighing all of the available inputs and making informed decisions about the trade-offs.

"Usage of features can be reminiscent of Jevons Paradox: consumption of a resource may increase as a response to greater efficiency in its use. ""build it and they will come""."

If you’re a leader, that’s what you’ve been asked to do: exercise judgement, assert that things are important.

Software is sustainable when, for the expected life span of the code, we are capable of responding to changes in dependencies, technology, or product requirements

Expertise pays off particularly well when combined with economies of scale.

“Because I said so” is a terrible reason to do things

If you spend all of your time working alone, you’re increasing the risk of unnecessary failure and cheating your potential for growth.

Thrives in ambiguity:Can deal with conflicting messages or directions, build consensus, and make progress against a problem, even when the environment is constantly shifting.

Values feedback: Has humility to both receive and give feedback gracefully and understands how valuable feedback is for personal (and team) development.

Challenges status quo: Is able to set ambitious goals and pursue them even when there might be resistance or inertia from others.

Puts the user first: has empathy and respect for users of products and pursues actions that are in their best interests.

Cares about the team: Has empathy and respect for coworkers and actively works to help them without being asked, improving team cohesion

Does the right thing: willing to make difficult or inconvenient decisions to protect the integrity of the team and product.

Three Pillars of team work:
Pillar 1: Humility You are not the center of the universe (or your code!). You’re neither omniscient nor infallible. You’re open to self-improvement Pillar 2: Respect You genuinely care about others you work with. You treat them kindly and appreciate their abilities and accomplishments. Pillar 3: Trust You believe others are competent and will do the right thing, and you’re OK with letting them drive when appropriate.

Software engineering is a team endeavor

Acknowledge the amount of time that you and your team spend communicating and in interpersonal conflict.

A small investment in understanding personalities and working styles of yourself and others can go a long way to improving productivity

Sharing expertise across an organization is not an easy task. Without a strong culture of learning, challenges can emerge.

Lack of psychological safety: An environment in which people are afraid to take risks or make mistakes in front of others because they fear being punished for it.

Information islands: Knowledge fragmentation that occurs in different parts of an organization that don’t communicate with one another or use shared resources.

Single point of failure for knowledge: A bottleneck that occurs when critical information is available from only a single person.

All or nothing expertise: A group of people that is split between people who know “everything” and novices, with little middle ground. This problem often reinforces itself if experts always do everything themselves and don’t take the time to develop new experts through mentoring or documentation.

Every expert was once a novice: an organization’s success depends on growing and investing in its people.

Tribal knowledge exists in the gap between what individual members know and what is documented. (Writing good docs is also hard)

Train, focus on learning and growth and build your own stable of experts

Setting the Stage: Psychological safety is critical to promoting a learning environment. To learn, you must first acknowledge that there are things you don’t understand. We should welcome such honesty rather than punish it.

An enormous part of learning is being able to try things and feeling safe to fail. In a healthy environment, people feel comfortable asking questions, being wrong, and learning new things.

Crucially, the mentor is there to be a safety net to talk to if the mentee doesn’t know whom else to ask for advice.

Bad Vibes: No feigned surprise: (“What?! I can’t believe you don’t know what the stack is!” No “well-actually”s: pedantic corrections that tend to be about grandstanding rather than precision. No back-seat driving: Interrupting an existing discussion to offer opinions without committing to the conversation. No subtle “-isms” (“It’s so easy my grandmother could do it!”)

Knowledge sharing starts with yourself. It is important to recognize that you always have something to learn, always be learning; always be asking questions. There is no magical day when you suddenly always know exactly what to do in every situation.

Embrace not knowing things as an area of opportunity rather than one to fear

It doesn’t matter whether you’re new to a team or a senior leader: you should always be in an environment in which there’s something to learn. If not, you stagnate.

It’s especially critical for those in leadership roles to model this behavior: it’s important not to mistakenly equate “seniority” with knowing everything.

patience and kindness when answering questions fosters an environment in which people feel safe looking for help. Making it easier to overcome the initial hesitation to ask a question sets the tone early.

Learning is not just about understanding new things; it also includes developing an understanding of the decisions behind the design and implementation of existing things.

If you don’t see the use of it, I certainly won’t let you clear it away. Go away and think. Then, when you can come back and tell me that you do see the use of it, I may allow you to destroy it. Chestertons Fence

The first time you learn something is the best time to see ways that the existing process/documentation and training materials can be improved.

Leadership includes growing future leaders by serving as mentors to junior staff.

Hey, I’m confused by the control flow in this section here. I wonder if the xyz code pattern might make this clearer and easier to maintain

Take extra care to make sure the postmortem document isn’t just a useless list of apologies or excuses or finger-pointing — that’s not its purpose.

A proper postmortem should always contain an explanation of what was learned and what is going to change as a result of the learning experience.

make sure that the postmortem is readily accessible and that the team really follows through on the proposed changes

A good postmortem should include the following: A brief summary of the event A timeline of the event, from discovery through investigation to resolution The primary cause of the event Impact and damage assessment A set of action items (with owners) to fix the problem immediately A set of action items to prevent the event from happening again Lessons learn

If you want to work effectively with a team or a large organization, be aware of your preferred working style and that of others.

Trade off with documentation: more generalized and less applicable to individual learners’ situations. maintenance cost required to keep information relevant and up to date over time. May be become harder to find as documentation grows in size

Cooperative:

  1. Basic questions or mistakes are guided in the proper direction
  2. Explanations are given with the intent of helping the person asking the question learn
  3. Responses are kind, patient, and helpful
  4. Interactions are shared discussions for understanding problems and finding solutions

Adversarial:

  1. Basic questions or mistakes are picked on, and the person asking the question is chastised
  2. Explanations are given with the intent of showing off one’s own knowledge
  3. Responses are condescending, snarky, and unconstructive
  4. Interactions are arguments with “winners” and “losers”

Context Learning is not just about understanding new things; it also includes developing an understanding of the decisions behind the design and implementation of existing things.

URL shorteners provide a predictable, memorable way to access things.

Above all, resist the urge to manage

As a servant leader, you should strive to create an atmosphere of humility, respect, and trust.

Traditional managers worry about how to get things done, whereas great managers worry about what things get done…(and trust their team to figure out how to do it).

It’s alright to fail, but fail as a team and learn from your failures. It’s one thing to laud individual successes, but looking to assign individual blame in the case of failure is a great way to divide a team and discourage risk taking across the board.

Antipattern: Hire Pushovers. Instead, you should strive to hire people who are smarter than you and can replace you.

"Antipattern: Ignore Low Performers. "Hope is not a strategy" "Sometimes you get to be the tooth fairy, other times you have to be the dentist". “How do you effectively coach a low performer?"

Antipattern: Ignore Human Issues. Regardless of the end result, a little bit of empathy goes a long way.

Antipattern: Be Everyone’s Friend. Don’t confuse friendship with leading with a soft touch. Remember that you can lead a team and build consensus without being a close friend of your team (or a monumental hard-ass).

Antipattern: Compromise the Hiring Bar. Do not compromise head count to build a mediocre team.

Antipattern: Treat Your Team Like Children. People tend to act the way you treat them, so if you treat them like children or prisoners, don’t be surprised when that’s how they behave. The best way to show your team that you don’t trust it is to treat team members like kids.

Lose the Ego This means that although you might be the one driving the team to consensus and helping to set the direction, the nuts and bolts of how to accomplish your goals are best decided by the people who are putting the product together

If you’re not micromanaging your team, you can be pretty certain the folks working in the trenches know the details of their work better than you do.

Mediating your reactions and maintaining your calm is more important as you lead more people. People and your team will look at your example.

The person asking for advice typically doesn’t want you to solve their problem, but rather to help them solve it, and the easiest way to do this is to ask this person questions.

Working to build team consensus is a leadership skill that is often used by unofficial leaders because it’s one way you can lead without any actual authority.

Sometimes, your team already has consensus about what you need to do, but it hit a roadblock and became stuck

Teaching people and giving them a chance to learn on their own can be incredibly difficult at first, but it’s a vital component of effective leadership

Primarily, you need three things: - experience with your team’s processes and systems. - the ability to explain things to someone else, - the ability to gauge how much help your mentee needs.

Teams can (and do) succeed without clear goals, but they typically waste a great deal of energy as each team member pulls the product in a slightly different direction.

Be Honest: “I won’t lie to you, but I will tell you when I can’t tell you something or if I just don’t know". "We’re quite sure that you’re not aware of this, but the way that you’re interacting with the team is alienating and angering them, and if you want to be effective, you need to refine your communication skills and we’re committed to helping you do that."

Happiness Tracking: - Try to gauge happiness periodically. - Track thankless tasks that need to be done, spread them. - Fun team outings to avoid burnout and exhaustion.

Happiness tracking: Ask about how they’re enjoying the work and what they’re looking forward to next.

A good simple way to track your team’s happiness is to ask the team member at the end of each one-on-one meeting, “What do you need?" or “Is there anything you need?”, if you ask this every time you have a one- on-one, you’ll find that eventually your team will remember this and sometimes even come to you with a laundry list of things it needs to make everyone’s job better.

but there are usually a few things that everyone would like to do in the next five years: - be promoted, - learn something new - launch something important. - work with friendly, smart people.

Delegate, but get your hands dirty.

Seek to replace yourself - give your team opportunities to take on more responsibilities.

Know when to make waves. The longer you wait to address problems, the more they’ll adversely affect the rest of the team and the more they’ll keep you up at night thinking about them.

Shield your team from chaos - Give your team air cover - Let your team know when they’re doing well.

It’s easy to say “yes” to something that’s easy to undo.

People are like plants: some are like cacti and need little water but lots of sunshine, others are like African violets and need diffuse light and moist soil and still others are like tomatoes and will truly excel if you give them a little fertilizer. (motivation and direction)

The book Drive, claims you can increase intrinsic motivation by giving people three things: autonomy, mastery, and purpose

Identify the Blinders of those before you. (horse blinders covering their eyes, leading to narrow POV on the problem/solution created by assumptions)

Identify the blinders: this is where you—with fresh eyes—have a great advantage.

Identify the Key Trade-Offs There is only the best answer for the moment. It’s your job to call out the trade-offs, explain them to everyone, and then help decide how to balance them.

Frame your process as continuous rebalancing of trade-offs. You need to make your teams comfortable with iteration. This keeps folks flexible and in a state of learning from their choices.

But rather represents a long, collective poisoning of the commons.

Unsustainable policies soon return to their prior levels.

Always be leaving: It’s not just your job to solve an ambiguous problem, but to get your organization to solve it by itself, without you present.

Build a “Self-Driving” team - Dividing the problem space. - Delegating the sub-problems to leaders. > What can I do that nobody else on my team can do? - Adjusting and Iterating: Always be leaving, adjacent problems, make space for new leaders.

Team identity: Take care in anchoring. A common mistake is to put a team in charge of a specific product rather than a general problem.

Scaling is doomed if unsustainable: As a leader, your most precious resource is your limited pool of time, attention, and energy.

The Cycle of Success. Analysis: First, you receive the problem and start to wrestle with it. You identify the blinders, find all the trade-offs, and build consensus about how to manage them. Struggle: You start moving on the work, whether or not your team thinks it’s ready. You prepare for failures, retries, and iteration. Traction: Eventually your team begins to figure things out. Reward: That’s right: the reward for success is more work…and more responsibility!

The “cycle” of success is more of a “spiral” your hiring doesn’t keep pace with the scaling. Your organization is scaling by tackling new problems and then figuring out how to compress them so that it can take on new, parallel struggle

"Important vs Urgent” All your communications channels are DDOS. ""I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent""" - US President, Dwight D. Eisenhower

Remember that your job as a leader is to do things that only you can do

Delegate Many of the urgent things you see can be delegated back to other leaders in your organization.

Schedule dedicated time. Regularly block out two hours or more to sit quietly and work only on important-but-not-urgent things

"Learn to Drop Balls You simply need to trust that things below your top-20%-importance threshold will either be taken care of or evolve appropriately there’s a middle ""60%"", which might contain a mix urgency or importance." Marie Kondo is an organizational consultant and the author of the extremely popular book The Life-Changing Magic of Tidying Up. Her philosophy is about effectively decluttering all of the junk from your house, but it works for abstract clutter, as well.

Managing your energy is just as important as managing your time. Take breaks during the day, weekends, off-time. Make it easy to disconnect

Worth Measuring? We should only measure a software process when a concrete decision will be made based on the outcome. - What result are you expecting, and why? - If the data supports your expected result, what action will be taken? - If we get a negative result, will appropriate action be taken? - Who is going to decide to take action on the result, and when would they do it? Sometimes its okay to not measure: - The results will be used only as vanity metrics to support something you were going to do anyway - You can’t afford to change the process/tools right now - Many Confounding Factors

A goal is a desired end result. Without reference to any metric. A signal is how you might know that you’ve achieved the end result. A metric is proxy for a signal. And its what we measure.

Rules and guidance should aim to support resilience to time and scaling.

Code review acts as the glue connecting engineers with one another, and the code review process is the primary developer workflow upon which almost all other processes must hang.

Always check your assumptions through someone else: optimize for the reader

There are usually three aspects of good documentation: completeness, accuracy, and clarity.

Documents are necessarily subjective; the quality of the document is measured not by the writer, but by the reader, and often quite asynchronous

Documentation is hugely important over time and scale. Documentation changes should leverage the existing developer workflow. Write for your audience, not yourself.

Small Tests: The primary constraint is that small tests must run in a single process.

Medium tests can span multiple processes, use threads, and can make blocking calls, including network calls only to localhost.

Large tests remove the localhost restriction imposed on medium tests. allowing the test and the system being tested to span across multiple machines.

Each flakey test investigation takes time away from something more productive that your team could be doing.

If test flakiness continues to grow, you will experience something much worse than lost productivity: a loss of confidence in the tests.

All tests should strive to be hermetic.

We recommend only measuring code-coverage from small tests to avoid coverage inflation that occurs when executing larger tests.

Do you have confidence that everything your customers expect to work, will work?

Do you feel confident you can catch breaking changes in your dependencies?

Are your tests stable and reliable?

Failing to keep a test suite deterministic and fast ensures it will become roadblock to productivity.

Choke Point: Orientation If they could reach all the new hires in the company, it could be an extremely effective avenue for introducing cultural change.

The new hires had no idea that they were being used as trojan horses to sneak cultural-change-ideas into their unsuspecting teams.

The belief was that successful ideas would spread, so the focus became demonstrating success.

Exploratory Testing is a fundamentally creative endeavor in which someone treats the application under test as a puzzle to be broken. maybe by executing an unexpected set of steps or by inserting unexpected data

Strive for Unchanging Tests The ideal test is unchanging: after it’s written, it never needs to change unless the requirements of the system under test change

Test via Public APIs write tests that invoke the system being tested in the same way its users would;

Test State, Not Interactions

Make Your Tests Complete and Concise Two high-level properties that help tests achieve clarity are completeness and conciseness.

rather than writing a test for each method, write a test for each behavior.

name tests after the behavior being tested

Eliminating flakiness of tests is a high priority.

Deprecation belongs to the discipline of software engineering than programming thinking about how to manage a system over time

it’s possible to plan for deprecation during the design of the system so that it’s easier to eventually decommission and remove it.

code is a liability, not an asset.

Deprecation is suited for systems that are: - demonstrably obsolete - replacement exists that provides comparable functionality.

Advisory deprecation allows system authors to encourage users in the desired direction.

Counterintuitively, the best way for compulsory deprecation efforts to scale is by localizing the expertise of migrating users to within a single team of experts

Any deprecation warning issued to a user needs to have two properties: actionability and relevance

A warning is actionable if the sample user can use the warning to: - actually perform some relevant action, not just in theory, but in practical terms.

A warning is relevant if it surfaces at a time when a user actually performs the indicated action.

It is still good for morale to celebrate incremental achievements in the deprecation process. The metrics used to evaluate the progress of the deprecation will be different

Preventing Backsliding. preventing the addition of new uses of the very thing being actively removed.

Removing things is often more difficult than building them to begin with because existing users are often using the system beyond its original design.

trunk-based development, relies heavily on the CI. merge and disable incomplete/untested features at runtime

We’ll more generally recognize that version numbers are timestamps, and that allowing version skew adds a dimensional complexity (time) that costs a lot that we can learn to avoid. It starts with something logically like a monorepo.

exploitation versus exploration in search problems. This feedback loop of exploitation is a downside view counts in search results problems.

Code Search grew from an organic replacement for grep into a central tool boosting developer productivity

Task-Based Build Systems the fundamental unit of work is the task. too much power to engineers and not enough power to the system, the build-system must be very conservative in how it schedules and executes build steps, there’s no way for the system to confirm that each script is doing what it should, so scripts tend to grow in complexity and end up being another thing that needs debugging

Task Based Build Systems - Lack of verifiability in the sub-tasks. - Difficulty of parallelizing build steps. - Difficulty performing incremental builds. - Difficulty maintaining and debugging scripts. imperative set of command...

Artifact-Based Build System a declarative manifest describing a - set of artifacts to build, - their dependencies, - set of options that affect how they’re built.

Characteristics of Effective Static Analysis - Scalability - Usability Focus on Developer Happiness.

Modern software is built on towering pillars of dependencies; but just because we can build those pillars doesn’t mean we’ve yet figured out how to keep them standing and stable over time. We are no longer disconnected islands built on one or two layers outside an API

Conflicting Requirements and Diamond Dependencies What happens when >1 nodes in the dependency network have conflicting requirements, and your organization depends on them both?

The Go programming language explicitly promises source compatibility between most releases, but no binary compatibility. You cannot build a library in Go with one version of the language and link that library into a Go program built with a different version of the language.

How Google Handles Importing Dependencies In short: we could do better. Some questions are asked on the suitability of the project. How popular is the project? How long will we be depending on this project? How often does the project make breaking changes? What sort of compatibility is the project aspiring to? How complicated would it be to implement that functionality within Google? What incentives will we have to keep this dependency up-to-date. Who will perform an upgrade? How difficult do we expect it to be to perform an upgrade?

Most problems in dependency management stop being problems when you can see exactly how your code is being used and know exactly the impact of any given change

A stable dependency-management scheme must therefore be flexible with time and scale. we can’t assume indefinite stability of any particular node in the dependency graph, nor can we assume that no new dependencies are added.

Large Scale Changes The same tools that make changing thousands of files efficient, also scale down reasonably well. The ones with the domain knowledge should conduct the change. Nobody likes unfunded mandates. Without good tests, such Large Scale Changes would be impossible and the codebase would quickly atrophy under its own weight.