Software Engineering - The Soft Parts (Addy Osmani) (z-library.sk, 1lib.sk, z-lib.sk)
Author: Addy Osmani
代码
No Description
📄 File Format:
PDF
💾 File Size:
13.1 MB
6
Views
0
Downloads
0.00
Total Donations
📄 Text Preview (First 20 pages)
ℹ️
Registered users can read the full content for free
Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.
📄 Page
1
1
📄 Page
2
Software Engineering - The Soft Parts By Addy Osmani 2
📄 Page
3
Table of Contents Prologue ..........................................................................................................5 About the Author ...........................................................................................6 Learning New Things .....................................................................................8 Mastery .....................................................................................................8 Think Critically and Formulate Well-Reasoned Arguments ...............9 Building a Strong Base .........................................................................11 Transferable Skills ..................................................................................11 Efficiency ................................................................................................12 Better Decision-Making ........................................................................12 Focus on the User and the Rest Will Follow .......................................13 Upgrading Your Skills ...........................................................................15 Depth and Breadth of Skills .................................................................17 To Experience Is To Learn ....................................................................18 Technical Complexity ..................................................................................20 Generic vs Specific Code .....................................................................20 Deep Modules .......................................................................................21 Learning on a Maintenance Project ....................................................21 Learning on a Green-Field Project ......................................................22 Definition of Done ................................................................................23 Phased Roll-Outs ...................................................................................23 Systematic Debugging .........................................................................23 Communication ............................................................................................26 Importance of Design Docs .................................................................26 Documentation Process .......................................................................26 Communication .....................................................................................27 Customized Communication ...............................................................27 3
📄 Page
4
Being Kind and Considerate ...............................................................28 Be Liberal in Telling Folks They're Doing a Great Job. .....................28 The Power of NO ...................................................................................29 Acceptance and Respect .....................................................................30 Information Sharing ..............................................................................30 Flexibility ................................................................................................30 Maintaining a Record ............................................................................31 Good Faith .............................................................................................31 Seniority ........................................................................................................33 Seniority and Strategic Thinking .........................................................33 Leading by Example .............................................................................34 Scale Your Effectiveness. ......................................................................36 Imposter Syndrome ..............................................................................36 Effective Teams .............................................................................................37 Building Trust .........................................................................................37 Understanding the Business Model ...................................................37 Increase Your Impact ............................................................................38 Mentoring .....................................................................................................40 Mentoring Others .................................................................................40 Organization-Wide Mentoring ............................................................41 Mentee's Role ........................................................................................41 Time and Work/Life Balance .......................................................................43 Time Management ................................................................................43 Conclusion ....................................................................................................52 4
📄 Page
5
Prologue Today I'll share some of the software engineering "soft skills" I've learned from my first 10 years on Google Chrome, where I am a Senior Staff Engineering Manager. On my 10th anniversary, I wanted to reflect on some of lessons that have stayed with me. I hope these prove useful to you during your career. Becoming a good engineer is about collecting experience. Each project, even small ones, is a chance to add new techniques and tools to your toolbox. Where this delivers even more value is when you can solve problems by pairing techniques learned on one project with tools learned working on another. It all adds up. I'll preface this by saying I am unimportant, unwise and unoriginal. Your mileage may vary :) With special thanks to Leena Sohoni, Joshua Cruz, Kara Erickson, Jeff Posnick, Houssein Djirdeh and Sriram Krishnan for their kind feedback and contributions to this book. © 2022 Addy Osmani. All rights reserved. 5
📄 Page
6
About the Author Addy Osmani is a Senior Staff Engineering Manager at Google working on Chrome. His career has focused on speed and developer tooling. He is the author of many open-source projects and has also written books like Image Optimization, and Learning JavaScript Design Patterns. You can find Addy on Twitter (https://twitter.com/addyosmani) and LinkedIn (https://www.linkedin.com/in/osmani/). 6
📄 Page
7
7
📄 Page
8
Learning New Things T he following pointers should help most junior or mid-career developers move forward, deal with changing technology, and build complex systems while following the standard processes in the software engineering paradigm and discovering new best practices. Apply first principles when you can. Learning to break down problems into smaller pieces is one of the most important skills in life. Mastery Technical mastery implies a high ratio of value shipped to hours worked. This means you can discern tasks that add value and help your team focus their energy in that direction. It also means you know how to avoid work that doesn't provide the team/company value - the best engineers can even steer whole teams away from work that isn't that useful. Work on what matters most. I often get asked, "How do I know if I'm making the best use of my time?". There will almost always be tasks you can fill your time with to "feel" busy. The real trick here is making sure you are working on the right things. If you want to move mountains, focus on tasks that move the needle, even if that movement is small. Some questions you can ask yourself: What are my goals? Are the tasks I'm focused on lining up with those goals? Could there be something I could do differently or better? Even asking yourself such questions can be extraordinarily powerful. 8
📄 Page
9
Think Critically and Formulate Well-Reasoned Arguments Critical thinking is the ability to use cognitive skills to think independently in order to make thoughtful decisions. Invest in this skill to improve your clarity of thought. As engineers, we can sometimes rush to solve a problem right away so it feels like we're making progress or looks like we're being responsive to stakeholders. This can introduce risks if we aren't fully considering causes and consequences. Put another way, critical thinking is thinking on purpose and forming your own conclusions. This goal-directed thinking can help you focus on root-cause issues that avoid future problems that arise from not keeping in mind causes and consequences. In broad strokes, some of the questions I like to ask based on critical thinking are: How do we know we're solving the right problem? How do we know we're solving the problem in the right way? (i.e. balancing rigor and efficiency, given our understanding of the problem and constraints) If we don't know the sources of our problem, how can we determine the root cause? How can we break the key question down into smaller questions that we can analyze further? Once we have one or more hypotheses, how do we structure work to evaluate them? What shortcuts might we take if we're under constraints (time pressure) without unduly compromising our analytics rigor around the question? Does the evidence sufficiently support the conclusions? How do we know when we are done? When is the solution "good enough"? 9
📄 Page
10
How do I communicate the solution clearly and logically to all stakeholders? I've found these questions often help. Sometimes we'll address the symptom of a problem, only to discover there are other symptoms that pop up. At other times, we might quickly ship a solution that creates more problems later down the road. With a lens on critical thinking, we might challenge assumptions, look closer at the risk/benefit, seek out contradictory evidence, evaluate credibility and look for more data to build confidence we are doing the right thing. For example, a common mistake I've seen engineers make is assuming correlation implies causation (i.e. just because two things correlate does not necessarily mean that one causes the other). A critical thinker might push back on assumptions such as this, asking why we believe them to be true. Critical thinkers: Raise mindful questions, formulating them clearly and precisely Collect and assess relevant information, validating how they might answer the question Arrive at well-reasoned conclusions and solutions, testing them against relevant criteria and standards Think open mindedly within alternative systems of thought, recognizing and assessing, as need be, their assumptions, implications, and practical consequences Communicate effectively with others in figuring out solutions to complex problems Note: Critical thinking has both aspects of being a "soft skill" and a "hard skill", so is included in this write-up. 10
📄 Page
11
Building a Strong Base Master the fundamentals and apply them repeatedly to acquire new skills. The long-term value of learning the fundamentals is that they are transferable. The short-term is that they help you make better decisions and can make code more efficient. Transferable Skills Transferable skills are those you can take with you from project to project. Let's talk about them in relation to the fundamentals. The fundamentals are the foundation of any software engineering career. There are two layers to them - macro and micro. The macro layer is the core of software engineering and the micro layer is the implementation (e.g. the tech stack, libraries, frameworks, etc.). At a macro level, you learn programming concepts that are largely transferable regardless of language. The syntax may differ, but the core ideas are still the same. This can include things like: data-structures (arrays, objects, modules, hashes), algorithms (searching, sorting), architecture (design patterns, state management) and even performance optimizations (e.g. eager vs lazy evaluation, memoization, caching, lazy-loading etc). These are concepts you'll use so frequently that knowing them backwards can have a lot of value. At a micro level, you learn the implementation of those concepts. This can include things like: the language you use ( JavaScript, Python, Ruby, etc), the frameworks you use (e.g. React, Angular, Vue etc), the backend you use (e.g. Django, Rails, etc), and the tech stack you use (e.g. Google App Engine, Google Cloud Platform, etc). These involve details that can be valuable to gain expertise in to be effective, but are not always transferable. 11
📄 Page
12
By learning the fundamentals, you gain the skillset and tools to then ignore the fundamentals and grow. That said, pragmatically, no one has time to learn everything at the beginning of their careers. There comes a point when you shouldn't over-index on the fundamentals and learn what is needed to actually build applications for the real world. This is where the "learn by doing" approach comes in. Efficiency Understanding the fundamentals well can help you write more efficient code. This includes concepts such as time complexity (the time it takes to run your code), memory usage, and the trade-offs between performance and maintainability. These ideas allow you to make trade- offs that are helpful when building any reasonably large application. Speed is often critical for modern applications and can often impact end-user experience in a noticeable way. Better Decision-Making Having a good understanding of macro and micro fundamentals can help you make better decisions. You can use the knowledge you've gained to make better decisions about which technologies to use and which ones to avoid based on the goals and constraints of any project. This can help you avoid the pitfalls of choosing the wrong technology or the wrong tool for the job. “You haven't mastered a tool until you understand when it should not be used." - @kelseyhightower Software engineering involves thinking about many different layers - the core languages, the implementation, the infrastructure, the tools, and the people. Only having a surface-level appreciation for these layers can absolutely let you build faster. But really knowing the 12
📄 Page
13
fundamentals (including O(n) time complexity) can help you go that much farther, especially when the landscape of languages and frameworks changes over time. Related reading: The value of fundamentals in Software Engineering (https://bit.ly/ softskills-value) Why learning the fundamentals matters (https://bit.ly/softskills- funmatter) Learn the fundamentals of a good developer mindset (https://bit.ly/ softskills-mindset) Focus on the User and the Rest Will Follow Start with the user experience and work backwards to the technology you need. Steve Jobs once famously said, "you've got to start with the customer experience and work backward to the technology. You can’t start with the technology then try to figure out where to sell it.” This quote has stuck with me, because as engineers, it's far too easy to start from a place of wanting to use specific solutions - whether due to popularity, developer experience or just personal preference - and try to find a way to rationalize using them. Instead, we should focus on who we're building for, what problems they have, and how the current options available are falling short. 13
📄 Page
14
Great user experiences come from combining both points of view - both the customer and technology. Show people what you think they want and pay attention to what they say. There is of course, immense nuance to this problem space - what engineering choices will allow you to deliver a great experience on mobile hardware? What choices will impact engineering velocity? or scale? or hiring?. Ultimately, we benefit from having a relentless focus on the customer first and then navigating what allows us to address their needs within the constraints we have to work with. The best software is built by engineers who have empathy for their users. Business success depends on customer satisfaction which often translates to user experience in the case of software. Understand how the end-users experience the product or service. Make sure your solutions do not hamper their ability to do their jobs efficiently. If you are in a position that allows you to interact with end-users directly, attempt to understand their needs and pain points better. 14
📄 Page
15
Upgrading Your Skills Choose what's right for your use case and not the flavor of the month. It's OK to use "boring” technology (what’s tried & tested) vs. the hype train. Languages, frameworks and libraries often evolve. Choose what helps deliver a great final product. When starting off a new project, begin with "boring" tech (but well understood) and then intentionally decide out of it to select the best tool for a problem. When picking new skills to learn or use, don't be afraid to choose something that's boring and not in the news. FOMO may not be productive when it comes to technology whether it be languages, frameworks, and libraries and tools. While it's important to know what to use, your main goal is to deliver an excellent final product. Please don't chase the new and shiny technologies unless you think they add value to your solutions. At the same time, don't shun something because it is not being talked about enough. Take advantage of new projects to learn new tech. At the same time, personal and hackathon projects can be a great opportunity to learn new tech. Many of us have fewer opportunities to start something completely brand new, as opposed to working on an existing codebase where many decisions have been made. Such projects can be a low-risk way to research new tech, evaluate its strengths and weaknesses (at a small scale) and build up some first- hand knowledge that could be valuable to you in the future. Be curious and never stop learning Write about what you learn. It pushes you to understand topics better. Sometimes the gaps in your knowledge only become clear when you try explaining things to others. It's OK if no one reads what you write. You get a lot out of just doing it for you. 15
📄 Page
16
Learning should be a continuous process - people who claim to know everything about a particular technology are often not experts. Real experts are proficient with the technology but realize there is always scope for learning and improvement. Curiosity drives learning - so if you are curious about a new framework, google it, read the docs, try the tutorials, read the source! Learning need not happen in a classroom. It can happen anywhere, anytime. Take half an hour each day to read a chapter from a textbook, listen to a technology podcast, read development blogs or learn a new programming language. It's powerful for leaders to admit when they don't know something. Having this confidence lowers the expectation that Senior Engineers have to know everything. You absolutely don't need to have all the answers, but being able to admit you're human and are committed to figuring out how to solve problems with your team is the important part. Leaders also admit when they make mistakes. It's important to teach your team how to handle mistakes with humility and the desire to learn and improve. The real world isn't perfect and it's totally okay to show your team it isn't perfect to prepare them for it. Be a caretaker, rather than an owner. In the early stages of open-source projects, it's common to think like an owner. You often directly own proving out value, working on features, answering issues and advocacy. This can be great for getting something adoption, but may not be the best way to scale a project later down the line when staffing changes or your own time gets limited. After the initial crunch, another way to think of evolving your role is towards being a caretaker, rather than an owner. A caretaker might focus on scaling themselves out. This can be done by sharing as much knowledge as is possible with other maintainers, contributors and the 16
📄 Page
17
community (via design docs, code comments, and other documented best practices). It also helps to grow the pool of reviewers with enough context to make the right decisions when you're no longer as involved. This is often what projects need to be sustainable many years down the road. Depth and Breadth of Skills Consider if being a jack of all trades and a master of one is right for you. One of the greatest skills you can master is learning how to learn. This should be a priority over say, just going deep on particular programming language or framework. It helps to stay curious. Once you have experience with this, you may question if you should aim to be a specialist or a jack of all trades. I personally like the idea of T-Shaped engineers (https://bit.ly/softskills- tshaped). These are engineers who are a deep expert in one or a small number of skills (the vertical bar of the T), but who have a basic understanding of many other skills needed to build and run a product (the horizontal bar). Some teams like to rotate team members through a range of different specializations to build more T-Shaped team members. I've found that in mid-large sized teams, it's been effective to have folks who possess specialized skills in one area and the skills, versatility, and aptitude for collaboration to fill in for other people if necessary. 17
📄 Page
18
To Experience Is To Learn When learning a new language, focus on building something tangible with it that gives you first-hand experience. If you are learning a new language, you need not memorize all its syntax or documentation to become a good developer. It's more important to know how to solve problems. Earn experience by writing a lot of relevant code or learning from existing code. The results should help you write efficient code in that language. As mentioned here (https://bit.ly/softskills-notcode), "The main value in software is not the code produced, but the knowledge accumulated by the people who produced it". However, please don't experiment in production when experimenting with new technology. 18
📄 Page
19
19
📄 Page
20
Technical Complexity Generic vs Specific Code Write code specifically for the problem at hand, but try to spot places where you can afford to make it a little generic. Often, we attempt to code things as generic as possible, and end up making what is effectively code soup that doesn't help accomplish the problem. Instead, building specifically for this problem, but trying to spot places it can be made just a little bit more generic, has altogether eliminated times I know I would've had to refactor again later if I hadn't been thinking of it. There are several principles commonly discussed that talk about design complexity. From the extreme programming world, you have: YAGNI or You aren't gonna need it, which states that programmers should not add functionality until it is necessary (https://bit.ly/ softskills-yagni) Do the simplest thing that could possibly work - to make rapid progress rather than plan for the future (https://bit.ly/softskills- simplest) Both these principles aim to prevent over-engineering (https://bit.ly/ softskills-overeng). However, these principles could be abused to create multiple simple solutions which do not integrate well. At the other end of the spectrum, you have the Abstraction principle (https://bit.ly/softskills-abstraction) that aims to reduce duplicate structures in the code whenever practical through abstraction and generalization. I prefer to take the middle ground between extreme abstraction and extreme simplicity by making code just a little generic. The AHA (Avoid hasty abstractions) principle promotes a similar idea (https://bit.ly/softskills-aha). 20
The above is a preview of the first 20 pages. Register to read the complete e-book.
Recommended for You
Loading recommended books...
Failed to load, please try again later