diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..143d929 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 4cb12d8..5f3f7ef 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ _book *.epub *.mobi *.pdf +/.vs/HowToBeAProgrammer/v15/.suo +/.vs/slnx.sqlite diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/HowToBeAProgrammer.iml b/.idea/HowToBeAProgrammer.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/HowToBeAProgrammer.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..69ace3f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6d167b4 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/1-Beginner/README.md b/1-Beginner/README.md deleted file mode 100644 index 519bcd9..0000000 --- a/1-Beginner/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# 1. Beginner - -- Personal Skills - - [Learn to Debug](Personal-Skills/01-Learn To Debug.md) - - [How to Debug by Splitting the Problem Space](Personal-Skills/02-How to Debug by Splitting the Problem Space.md) - - [How to Remove an Error](Personal-Skills/03-How to Remove an Error.md) - - [How to Debug Using a Log](Personal-Skills/04-How to Debug Using a Log.md) - - [How to Understand Performance Problems](Personal-Skills/05-How to Understand Performance Problems.md) - - [How to Fix Performance Problems](Personal-Skills/06-How to Fix Performance Problems.md) - - [How to Optimize Loops](Personal-Skills/07-How to Optimize Loops.md) - - [How to Deal with I/O Expense](Personal-Skills/08-How to Deal with IO Expense.md) - - [How to Manage Memory](Personal-Skills/09-How to Manage Memory.md) - - [How to Deal with Intermittent Bugs](Personal-Skills/10-How to Deal with Intermittent Bugs.md) - - [How to Learn Design Skills](Personal-Skills/11-How to Learn Design Skills.md) - - [How to Conduct Experiments](Personal-Skills/12-How to Conduct Experiments.md) -- Team Skills - - [Why Estimation is Important](Team-Skills/01-Why Estimation is Important.md) - - [How to Estimate Programming Time](Team-Skills/02-How to Estimate Programming Time.md) - - [How to Find Out Information](Team-Skills/03-How to Find Out Information.md) - - [How to Utilize People as Information Sources](Team-Skills/04-How to Utilize People as Information Sources.md) - - [How to Document Wisely](Team-Skills/05-How to Document Wisely.md) - - [How to Work with Poor Code](Team-Skills/06-How to Work with Poor Code.md) - - [How to Use Source Code Control](Team-Skills/07-How to Use Source Code Control.md) - - [How to Unit Test](Team-Skills/08-How to Unit Test.md) - - [Take Breaks when Stumped](Team-Skills/09-Take Breaks when Stumped.md) - - [How to Recognize When to Go Home](Team-Skills/10-How to Recognize When to Go Home.md) - - [How to Deal with Difficult People](Team-Skills/11-How to Deal with Difficult People.md) \ No newline at end of file diff --git a/2-Intermediate/Judgment/09-Design Patterns.md b/2-Intermediate/Judgment/09-Design Patterns.md new file mode 100644 index 0000000..53991d3 --- /dev/null +++ b/2-Intermediate/Judgment/09-Design Patterns.md @@ -0,0 +1,30 @@ +# Design Patterns + +Design Patterns can be seen as repeatable solutions to common problems arising in software design. They provide a great, language-agnostic +way of talking about software architecture. + +"Head First Design Patterns" explains simply: + +> Design patterns don't go directly into your code, they first go into your BRAIN. Once you've loaded your brain with good working +knowledge of patterns you can start to apply them to your new designs + +There are a number of benefits to considering using a design pattern: + +- Helps your system prepare for accommodating change - an inevitability of software development +- Allows for a shared language when describing a system - you can "say more with less" +- Can lead to a better designed system (through *appropriate use* of a design pattern) + +There are 23 'Gang of Four' patterns that are generally considered the foundation for all other patterns. They are categorised into three groups: Creational, Structural and Behavioural. + +## Criticisms + +[SourceMaking](https://sourcemaking.com/design_patterns) highlights some of the criticisms of using design patterns: + + - Targets the wrong problem + - Lacks formal foundations + - Leads to inefficient solutions + - Does not differ significantly from other abstractions + + +Some argue that design patterns ultimately boil down to good software design with careful consideration of SOLID principles. + [Jeff Atwood also has some thoughts on design patterns](http://blog.codinghorror.com/rethinking-design-patterns/) diff --git a/2-Intermediate/Personal-Skills/01-How to Stay Motivated.md b/2-Intermediate/Personal-Skills/01-How to Stay Motivated.md deleted file mode 100644 index e441581..0000000 --- a/2-Intermediate/Personal-Skills/01-How to Stay Motivated.md +++ /dev/null @@ -1,15 +0,0 @@ -# How to Stay Motivated - -It is a wonderful and surprising fact that programmers are highly motivated by the desire to create artifacts that are beautiful, useful, or nifty. This desire is not unique to programmers nor universal but it is so strong and common among programmers that it separates them from others in other roles. - -This has practical and important consequences. If programmers are asked to do something that is not beautiful, useful, or nifty, they will have low morale. There's a lot of money to be made doing ugly, stupid, and boring stuff; but in the end, fun will make the most money for the company. - -Obviously, there are entire industries organized around motivational techniques some of which apply here. The things that are specific to programming that I can identify are: - -- Use the best language for the job. -- Look for opportunities to apply new techniques, languages, and technologies. -- Try to either learn or teach something, however small, in each project. - -Finally, if possible, measure the impact of your work in terms of something that will be personally motivating. For example, when fixing bugs, counting the number of bugs that I have fixed is not at all motivational to me, because it is independent of the number that may still exist, and is also affects the total value I'm adding to my company's customers in only the smallest possible way. Relating each bug to a happy customer, however, *is* personally motivating to me. - -Next [How to be Widely Trusted](02-How to be Widely Trusted.md) \ No newline at end of file diff --git a/2-Intermediate/README.md b/2-Intermediate/README.md deleted file mode 100644 index 5271d19..0000000 --- a/2-Intermediate/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# 2. Intermediate - -- Personal Skills - - [How to Stay Motivated](Personal-Skills/01-How to Stay Motivated.md) - - [How to be Widely Trusted](Personal-Skills/02-How to be Widely Trusted.md) - - [How to Tradeoff Time vs. Space](Personal-Skills/03-How to Tradeoff Time vs Space.md) - - [How to Stress Test](Personal-Skills/04-How to Stress Test.md) - - [How to Balance Brevity and Abstraction](Personal-Skills/05-How to Balance Brevity and Abstraction.md) - - [How to Learn New Skills](Personal-Skills/06-How to Learn New Skills.md) - - [Learn to Type](Personal-Skills/07-Learn to Type.md) - - [How to Do Integration Testing](Personal-Skills/08-How to Do Integration Testing.md) - - [Communication Languages](Personal-Skills/09-Communication Languages.md) - - [Heavy Tools](Personal-Skills/10-Heavy Tools.md) - - [How to analyze data](Personal-Skills/11-How to analyze data.md) -- Team Skills - - [How to Manage Development Time](Team-Skills/01-How to Manage Development Time.md) - - [How to Manage Third-Party Software Risks](Team-Skills/02-How to Manage Third-Party Software Risks.md) - - [How to Manage Consultants](Team-Skills/03-How to Manage Consultants.md) - - [How to Communicate the Right Amount](Team-Skills/04-How to Communicate the Right Amount.md) - - [How to Disagree Honestly and Get Away with It](Team-Skills/05-How to Disagree Honestly and Get Away with It.md) -- Judgment - - [How to Tradeoff Quality Against Development Time](Judgment/01-How to Tradeoff Quality Against Development Time.md) - - [How to Manage Software System Dependence](Judgment/02-How to Manage Software System Dependence.md) - - [How to Decide if Software is Too Immature](Judgment/03-How to Decide if Software is Too Immature.md) - - [How to Make a Buy vs. Build Decision](Judgment/04-How to Make a Buy vs Build Decision.md) - - [How to Grow Professionally](Judgment/05-How to Grow Professionally.md) - - [How to Evaluate Interviewees](Judgment/06-How to Evaluate Interviewees.md) - - [How to Know When to Apply Fancy Computer Science](Judgment/07-How to Know When to Apply Fancy Computer Science.md) - - [How to Talk to Non-Engineers](Judgment/08-How to Talk to Non-Engineers.md) \ No newline at end of file diff --git a/2-Intermediate/Team-Skills/03-How to Manage Consultants.md b/2-Intermediate/Team-Skills/03-How to Manage Consultants.md deleted file mode 100644 index 6844c3b..0000000 --- a/2-Intermediate/Team-Skills/03-How to Manage Consultants.md +++ /dev/null @@ -1,9 +0,0 @@ -# How to Manage Consultants - -Use consultants, but don't rely on them. They are wonderful people and deserve a great deal of respect. Since they get to see a lot of different projects, they often know more about specific technologies and even programming techniques than you will. The best way to use them is as educators in-house that can teach by example. - -However, they usually cannot become part of the team in the same sense that regular employees are, if only because you may not have enough time to learn their strengths and weaknesses. Their financial commitment is much lower. They can move more easily. They may have less to gain if the company does well. Some will be good, some will be average, and some will be bad, but hopefully your selection of consultants will not be as careful as your selection of employees, so you will get more bad ones. - -If consultants are going to write code, you must review it carefully as you go along. You cannot get to the end of the a project with the risk of a large block of code that has not been reviewed. This is true of all team members, really, but you will usually have more knowledge of the team members closer to you. - -Next [How to Communicate the Right Amount](04-How to Communicate the Right Amount.md) \ No newline at end of file diff --git a/3-Advanced/README.md b/3-Advanced/README.md deleted file mode 100644 index 7f66191..0000000 --- a/3-Advanced/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# 3. Advanced - -- Technological Judgment - - [How to Tell the Hard From the Impossible](Technical-Judgment/01-How to Tell the Hard From the Impossible.md) - - [How to Utilize Embedded Languages](Technical-Judgment/02-How to Utilize Embedded Languages.md) - - [Choosing Languages](Technical-Judgment/03-Choosing Languages.md) -- Compromising Wisely - - [How to Fight Schedule Pressure](Compromising-Wisely/01-How to Fight Schedule Pressure.md) - - [How to Understand the User](Compromising-Wisely/02-How to Understand the User.md) - - [How to Get a Promotion](Compromising-Wisely/03-How to Get a Promotion.md) -- Serving Your Team - - [How to Develop Talent](Serving-Your-Team/01-How to Develop Talent.md) - - [How to Choose What to Work On](Serving-Your-Team/02-How to Choose What to Work On.md) - - [How to Get the Most From Your Team-mates](Serving-Your-Team/03-How to Get the Most From Your Teammates.md) - - [How to Divide Problems Up](Serving-Your-Team/04-How to Divide Problems Up.md) - - [How to Handle Boring Tasks](Serving-Your-Team/05-How to Handle Boring Tasks.md) - - [How to Gather Support for a Project](Serving-Your-Team/06-How to Gather Support for a Project.md) - - [How to Grow a System](Serving-Your-Team/07-How to Grow a System.md) - - [How to Communicate Well](Serving-Your-Team/08-How to Communicate Well.md) - - [How to Tell People Things They Don't Want to Hear](Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md) - - [How to Deal with Managerial Myths](Serving-Your-Team/10-How to Deal with Managerial Myths.md) - - [How to Deal with Organizational Chaos](Serving-Your-Team/11-How to Deal with Organizational Chaos.md) \ No newline at end of file diff --git a/3-Advanced/Technical-Judgment/01-How to Tell the Hard From the Impossible.md b/3-Advanced/Technical-Judgment/01-How to Tell the Hard From the Impossible.md deleted file mode 100644 index a1146c0..0000000 --- a/3-Advanced/Technical-Judgment/01-How to Tell the Hard From the Impossible.md +++ /dev/null @@ -1,9 +0,0 @@ -# How to Tell the Hard From the Impossible - -It is our job to do the hard and discern the impossible. From the point of view of most working programmers, something is impossible if either it cannot be grown from a simple system or it cannot be estimated. By this definition what is called research is impossible. A large volume of mere work is hard, but not necessarily impossible. - -The distinction is not facetious because you may very well be asked to do what is practically impossible, either from a scientific point of view or a software engineering point of view. It then becomes your job to help the entrepreneur find a reasonable solution which is merely hard and gets most of what they wanted. A solution is merely hard when it can be confidently scheduled and the risks are understood. - -It is impossible to satisfy a vague requirement, such as ‘Build a system that will compute the most attractive hair style and colour for any person.’ If the requirement can be made more crisp, it will often become merely hard, such as ‘Build a system to compute an attractive hair style and colour for a person, allow them to preview it and make changes, and have the customer satisfaction based on the original styling be so great that we make a lot of money.’ If there is not crisp definition of success, you will not succeed. - -Next [How to Utilize Embedded Languages](02-How to Utilize Embedded Languages.md) \ No newline at end of file diff --git a/LANGS.md b/LANGS.md new file mode 100644 index 0000000..125fbf7 --- /dev/null +++ b/LANGS.md @@ -0,0 +1,6 @@ +* [English](en/) +* [Spanish](es/) +* [Chinese](zh/) +* [Japanese](jp/) +* [Russian](ru/) +* [Chinese-Traditional](zh-traditional/) diff --git a/README.md b/README.md index 903288f..e6d93ab 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ # How to be a Programmer: Community Version - +[//]: # (Version:1.1.0) Robert L. Read with Community Copyright 2002, 2003, 2016 Robert L. Read Licensed under [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). +[Available on gitbook to read](https://braydie.gitbook.io/how-to-be-a-programmer/) + +[Available to buy as a hardcover book (cost covers production & shipping only)](http://www.blurb.com/b/6999069-how-to-be-a-programmer) - Edition 1, published 04/01/16 + ## Introduction -To be a good programmer is difficult and noble. The hardest part of making real a collective vision of a software project is dealing with one's coworkers and customers. Writing computer programs is important and takes great intelligence and skill. But it is really child's play compared to everything else that a good programmer must do to make a software system that succeeds for both the customer and myriad colleagues for whom she is partially responsible. In this essay I attempt to summarize as concisely as possible those things that I wish someone had explained to me when I was twenty-one. +To be a good programmer is difficult and noble. The hardest part of making real a collective vision of a software project is dealing with one's coworkers and customers. Writing computer programs is important and takes great intelligence and skill. But it is really child's play compared to everything else that a good programmer must do to make a software system that succeeds for both the customer and myriad colleagues for whom he or she is partially responsible. In this essay I attempt to summarize as concisely as possible those things that I wish someone had explained to me when I was twenty-one. This is very subjective and, therefore, this essay is doomed to be personal and somewhat opinionated. I confine myself to problems that a programmer is very likely to have to face in her work. Many of these problems and their solutions are so general to the human condition that I will probably seem preachy. I hope in spite of this that this essay will be useful. @@ -19,85 +23,91 @@ Welcome to the tribe. ## Contents -1. [Beginner](1-Beginner) +**Also available in [Chinese](zh/README.md), [Japanese](jp/README.md),[Spanish](es/README.md), and [Russian](ru/README.md)** + + +1. [Beginner](en/1-Beginner) - Personal Skills - - [Learn to Debug](1-Beginner/Personal-Skills/01-Learn To Debug.md) - - [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How to Debug by Splitting the Problem Space.md) - - [How to Remove an Error](1-Beginner/Personal-Skills/03-How to Remove an Error.md) - - [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How to Debug Using a Log.md) - - [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How to Understand Performance Problems.md) - - [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How to Fix Performance Problems.md) - - [How to Optimize Loops](1-Beginner/Personal-Skills/07-How to Optimize Loops.md) - - [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How to Deal with IO Expense.md) - - [How to Manage Memory](1-Beginner/Personal-Skills/09-How to Manage Memory.md) - - [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How to Deal with Intermittent Bugs.md) - - [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How to Learn Design Skills.md) - - [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How to Conduct Experiments.md) + - [Learn to Debug](en/1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [How to Debug by Splitting the Problem Space](en/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [How to Remove an Error](en/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [How to Debug Using a Log](en/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [How to Understand Performance Problems](en/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [How to Fix Performance Problems](en/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [How to Optimize Loops](en/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [How to Deal with I/O Expense](en/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [How to Manage Memory](en/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [How to Deal with Intermittent Bugs](en/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [How to Learn Design Skills](en/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [How to Conduct Experiments](en/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) - Team Skills - - [Why Estimation is Important](1-Beginner/Team-Skills/01-Why Estimation is Important.md) - - [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How to Estimate Programming Time.md) - - [How to Find Out Information](1-Beginner/Team-Skills/03-How to Find Out Information.md) - - [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How to Utilize People as Information Sources.md) - - [How to Document Wisely](1-Beginner/Team-Skills/05-How to Document Wisely.md) - - [How to Work with Poor Code](1-Beginner/Team-Skills/06-How to Work with Poor Code.md) - - [How to Use Source Code Control](1-Beginner/Team-Skills/07-How to Use Source Code Control.md) - - [How to Unit Test](1-Beginner/Team-Skills/08-How to Unit Test.md) - - [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take Breaks when Stumped.md) - - [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How to Recognize When to Go Home.md) - - [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How to Deal with Difficult People.md) -2. [Intermediate](2-Intermediate) + - [Why Estimation is Important](en/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [How to Estimate Programming Time](en/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [How to Find Out Information](en/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [How to Utilize People as Information Sources](en/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [How to Document Wisely](en/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [How to Work with Poor Code](en/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [How to Use Source Code Control](en/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [How to Unit Test](en/1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [Take Breaks when Stumped](en/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [How to Recognize When to Go Home](en/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [How to Deal with Difficult People](en/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [Intermediate](en/2-Intermediate) - Personal Skills - - [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How to Stay Motivated.md) - - [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How to be Widely Trusted.md) - - [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How to Tradeoff Time vs Space.md) - - [How to Stress Test](2-Intermediate/Personal-Skills/04-How to Stress Test.md) - - [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How to Balance Brevity and Abstraction.md) - - [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How to Learn New Skills.md) - - [Learn to Type](2-Intermediate/Personal-Skills/07-Learn to Type.md) - - [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How to Do Integration Testing.md) - - [Communication Languages](2-Intermediate/Personal-Skills/09-Communication Languages.md) - - [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy Tools.md) - - [How to analyze data](2-Intermediate/Personal-Skills/11-How to analyze data.md) + - [How to Stay Motivated](en/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [How to be Widely Trusted](en/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [How to Tradeoff Time vs. Space](en/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [How to Stress Test](en/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [How to Balance Brevity and Abstraction](en/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [How to Learn New Skills](en/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Learn to Type](en/2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [How to Do Integration Testing](en/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Communication Languages](en/2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [Heavy Tools](en/2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [How to analyze data](en/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) - Team Skills - - [How to Manage Development Time](2-Intermediate/Team-Skills/01-How to Manage Development Time.md) - - [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How to Manage Third-Party Software Risks.md) - - [How to Manage Consultants](2-Intermediate/Team-Skills/03-How to Manage Consultants.md) - - [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How to Communicate the Right Amount.md) - - [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How to Disagree Honestly and Get Away with It.md) + - [How to Manage Development Time](en/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [How to Manage Third-Party Software Risks](en/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [How to Manage Consultants](en/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [How to Communicate the Right Amount](en/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [How to Disagree Honestly and Get Away with It](en/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) - Judgment - - [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How to Tradeoff Quality Against Development Time.md) - - [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How to Manage Software System Dependence.md) - - [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How to Decide if Software is Too Immature.md) - - [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How to Make a Buy vs Build Decision.md) - - [How to Grow Professionally](2-Intermediate/Judgment/05-How to Grow Professionally.md) - - [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How to Evaluate Interviewees.md) - - [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How to Know When to Apply Fancy Computer Science.md) - - [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How to Talk to Non-Engineers.md) -3. [Advanced](3-Advanced) + - [How to Tradeoff Quality Against Development Time](en/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [How to Manage Software System Dependence](en/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [How to Decide if Software is Too Immature](en/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [How to Make a Buy vs. Build Decision](en/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [How to Grow Professionally](en/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [How to Evaluate Interviewees](en/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [How to Know When to Apply Fancy Computer Science](en/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [How to Talk to Non-Engineers](en/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) + - Mentoring + - [How to Be Mentored](en/2-Intermediate/Mentoring/How-To-Be-Mentored.md) + - [How to Mentor Others](en/2-Intermediate/Mentoring/How-to-Mentor-Others.md) +3. [Advanced](en/3-Advanced) - Technological Judgment - - [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How to Tell the Hard From the Impossible.md) - - [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How to Utilize Embedded Languages.md) - - [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing Languages.md) - - Compromising Wisely - - [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How to Fight Schedule Pressure.md) - - [How to Understand the User](3-Advanced/Compromising-Wisely/02-How to Understand the User.md) - - [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How to Get a Promotion.md) - - Serving Your Team - - [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How to Develop Talent.md) - - [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How to Choose What to Work On.md) - - [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How to Get the Most From Your Teammates.md) - - [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How to Divide Problems Up.md) - - [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How to Handle Boring Tasks.md) - - [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How to Gather Support for a Project.md) - - [How to Grow a System](3-Advanced/Serving-Your-Team/07-How to Grow a System.md) - - [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How to Communicate Well.md) - - [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md) - - [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How to Deal with Managerial Myths.md) - - [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How to Deal with Organizational Chaos.md) -4. [Glossary](GLOSSARY.md) -5. [Appendix A - Bibliography/Websiteography](5-Bibliography.md) -6. [Appendix B - History (As of January 2016)](6-History.md) -6. [Appendix C - Contributions (As of January 2016)](7-Contributions.md) + - [How to Tell the Hard From the Impossible](en/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [How to Utilize Embedded Languages](en/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Choosing Languages](en/3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - Compromising Wisely + - [How to Fight Schedule Pressure](en/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [How to Understand the User](en/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [How to Get a Promotion](en/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - Serving Your Team + - [How to Develop Talent](en/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [How to Choose What to Work On](en/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [How to Get the Most From Your Team-mates](en/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [How to Divide Problems Up](en/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [How to Handle Boring Tasks](en/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [How to Gather Support for a Project](en/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [How to Grow a System](en/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [How to Communicate Well](en/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [How to Tell People Things They Don't Want to Hear](en/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [How to Deal with Managerial Myths](en/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [How to Deal with Organizational Chaos](en/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [Glossary](en/GLOSSARY.md) +5. [Appendix A - Bibliography/Websiteography](en/5-Bibliography.md) +6. [Appendix B - History (As of January 2016)](en/6-History.md) +6. [Appendix C - Contributions (As of January 2016)](en/7-Contributions.md) Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/SUMMARY.md b/SUMMARY.md deleted file mode 100644 index 3a73b06..0000000 --- a/SUMMARY.md +++ /dev/null @@ -1,80 +0,0 @@ -# Summary - -* [Beginner](1-Beginner/README.md) - * Personal Skills - * [Learn to Debug](1-Beginner/Personal-Skills/01-Learn To Debug.md) - * [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How to Debug by Splitting the Problem Space.md) - * [How to Remove an Error](1-Beginner/Personal-Skills/03-How to Remove an Error.md) - * [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How to Debug Using a Log.md) - * [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How to Understand Performance Problems.md) - * [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How to Fix Performance Problems.md) - * [How to Optimize Loops](1-Beginner/Personal-Skills/07-How to Optimize Loops.md) - * [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How to Deal with IO Expense.md) - * [How to Manage Memory](1-Beginner/Personal-Skills/09-How to Manage Memory.md) - * [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How to Deal with Intermittent Bugs.md) - * [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How to Learn Design Skills.md) - * [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How to Conduct Experiments.md) - * Team Skills - * [Why Estimation is Important](1-Beginner/Team-Skills/01-Why Estimation is Important.md) - * [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How to Estimate Programming Time.md) - * [How to Find Out Information](1-Beginner/Team-Skills/03-How to Find Out Information.md) - * [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How to Utilize People as Information Sources.md) - * [How to Document Wisely](1-Beginner/Team-Skills/05-How to Document Wisely.md) - * [How to Work with Poor Code](1-Beginner/Team-Skills/06-How to Work with Poor Code.md) - * [How to Use Source Code Control](1-Beginner/Team-Skills/07-How to Use Source Code Control.md) - * [How to Unit Test](1-Beginner/Team-Skills/08-How to Unit Test.md) - * [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take Breaks when Stumped.md) - * [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How to Recognize When to Go Home.md) - * [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How to Deal with Difficult People.md) -* [Intermediate](2-Intermediate/README.md) - * Personal Skills - * [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How to Stay Motivated.md) - * [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How to be Widely Trusted.md) - * [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How to Tradeoff Time vs Space.md) - * [How to Stress Test](2-Intermediate/Personal-Skills/04-How to Stress Test.md) - * [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How to Balance Brevity and Abstraction.md) - * [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How to Learn New Skills.md) - * [Learn to Type](2-Intermediate/Personal-Skills/07-Learn to Type.md) - * [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How to Do Integration Testing.md) - * [Communication Languages](2-Intermediate/Personal-Skills/09-Communication Languages.md) - * [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy Tools.md) - * [How to analyze data](2-Intermediate/Personal-Skills/11-How to analyze data.md) - * Team Skills - * [How to Manage Development Time](2-Intermediate/Team-Skills/01-How to Manage Development Time.md) - * [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How to Manage Third-Party Software Risks.md) - * [How to Manage Consultants](2-Intermediate/Team-Skills/03-How to Manage Consultants.md) - * [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How to Communicate the Right Amount.md) - * [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How to Disagree Honestly and Get Away with It.md) - * Judgment - * [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How to Tradeoff Quality Against Development Time.md) - * [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How to Manage Software System Dependence.md) - * [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How to Decide if Software is Too Immature.md) - * [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How to Make a Buy vs Build Decision.md) - * [How to Grow Professionally](2-Intermediate/Judgment/05-How to Grow Professionally.md) - * [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How to Evaluate Interviewees.md) - * [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How to Know When to Apply Fancy Computer Science.md) - * [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How to Talk to Non-Engineers.md) -* [Advanced](3-Advanced/README.md) - * Technological Judgment - * [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How to Tell the Hard From the Impossible.md) - * [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How to Utilize Embedded Languages.md) - * [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing Languages.md) - * Compromising Wisely - * [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How to Fight Schedule Pressure.md) - * [How to Understand the User](3-Advanced/Compromising-Wisely/02-How to Understand the User.md) - * [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How to Get a Promotion.md) - * Serving Your Team - * [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How to Develop Talent.md) - * [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How to Choose What to Work On.md) - * [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How to Get the Most From Your Teammates.md) - * [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How to Divide Problems Up.md) - * [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How to Handle Boring Tasks.md) - * [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How to Gather Support for a Project.md) - * [How to Grow a System](3-Advanced/Serving-Your-Team/07-How to Grow a System.md) - * [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How to Communicate Well.md) - * [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md) - * [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How to Deal with Managerial Myths.md) - * [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How to Deal with Organizational Chaos.md) -* [Appendix A * Bibliography/Websiteography](5-Bibliography.md) -* [Appendix B * History (As of January 2016)](6-History.md) -* [Appendix C * Contributions (As of January 2016)](7-Contributions.md) diff --git a/1-Beginner/Personal-Skills/01-Learn To Debug.md b/en/1-Beginner/Personal-Skills/01-Learn-To-Debug.md similarity index 80% rename from 1-Beginner/Personal-Skills/01-Learn To Debug.md rename to en/1-Beginner/Personal-Skills/01-Learn-To-Debug.md index 0e2e0bf..8cb8976 100644 --- a/1-Beginner/Personal-Skills/01-Learn To Debug.md +++ b/en/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -1,5 +1,5 @@ # Learn to Debug - +[//]: # (Version:1.0.0) Debugging is the cornerstone of being a programmer. The first meaning of the verb "debug" is to remove errors, but the meaning that really matters is to see into the execution of a program by examining it. A programmer that cannot debug effectively is blind. Idealists, those who think design, analysis, complexity theory, and the like are more fundamental than debugging, are not working programmers. The working programmer does not live in an ideal world. Even if you are perfect, you are surrounded by and must interact with code written by major software companies, organizations like GNU, and your colleagues. Most of this code is imperfect and imperfectly documented. Without the ability to gain visibility into the execution of this code, the slightest bump will throw you permanently. Often this visibility can be gained only by experimentation: that is, debugging. @@ -14,8 +14,8 @@ The common ways of looking into the ‘innards’ of an executing program can be - Printlining - Making a temporary modification to the program, typically adding lines that print information out, and - Logging - Creating a permanent window into the programs execution in the form of a log. -Debugging tools are wonderful when they are stable and available, but the printlining and logging are even more important. Debugging tools often lag behind language development, so at any point in time they may not be available. In addition, because the debugging tool may subtly change the way the program executes it may not always be practical. Finally, there are some kinds of debugging, such as checking an assertion against a large data structure, that require writing code and changing the execution of the program. It is good to know how to use debugging tools when they are stable, but it is critical to be able to employ the other two methods. +Debugging tools are wonderful when they are stable and available, but printlining and logging are even more important. Debugging tools often lag behind language development, so at any point in time they may not be available. In addition, because the debugging tool may subtly change the way the program executes it may not always be practical. Finally, there are some kinds of debugging, such as checking an assertion against a large data structure, that require writing code and changing the execution of the program. It is good to know how to use debugging tools when they are stable, but it is critical to be able to employ the other two methods. Some beginners fear debugging when it requires modifying code. This is understandable - it is a little like exploratory surgery. But you have to learn to poke at the code and make it jump; you have to learn to experiment on it and understand that nothing that you temporarily do to it will make it worse. If you feel this fear, seek out a mentor - we lose a lot of good programmers at the delicate onset of their learning to this fear. -Next [How to Debug by Splitting the Problem Space](02-How to Debug by Splitting the Problem Space.md) +Next [How to Debug by Splitting the Problem Space](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/1-Beginner/Personal-Skills/02-How to Debug by Splitting the Problem Space.md b/en/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md similarity index 94% rename from 1-Beginner/Personal-Skills/02-How to Debug by Splitting the Problem Space.md rename to en/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md index c536c89..9af47f3 100644 --- a/1-Beginner/Personal-Skills/02-How to Debug by Splitting the Problem Space.md +++ b/en/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -1,15 +1,15 @@ # How to Debug by Splitting the Problem Space - +[//]: # (Version:1.0.0) Debugging is fun, because it begins with a mystery. You think it should do something, but instead it does something else. It is not always quite so simple---any examples I can give will be contrived compared to what sometimes happens in practice. Debugging requires creativity and ingenuity. If there is a single key to debugging it is to use the divide and conquer technique on the mystery. Suppose, for example, you created a program that should do ten things in a sequence. When you run it, it crashes. Since you didn't program it to crash, you now have a mystery. When you look at the output, you see that the first seven things in the sequence were run successfully. The last three are not visible from the output, so now your mystery is smaller: ‘It crashed on thing #8, #9, or #10.’ Can you design an experiment to see which thing it crashed on? Sure. You can use a debugger or we can add printline statements (or the equivalent in whatever language you are working in) after #8 and #9. When we run it again, our mystery will be smaller, such as ‘It crashed on thing #9.’ I find that bearing in mind exactly what the mystery is at any point in time helps keep one focused. When several people are working together under pressure on a problem it is easy to forget what the most important mystery is. -The key to divide and conquer as a debugging technique is the same as it is for algorithm design: as long as you do a good job splitting the mystery in the middle, you won't have to split it too many times, and you will be debugging quickly. But what is the middle of a mystery? There is where true creativity and experience comes in. +The key to divide and conquer as a debugging technique is the same as it is for algorithm design: as long as you do a good job splitting the mystery in the middle, you won't have to split it too many times, and you will be debugging quickly. But what is the middle of a mystery? This is where true creativity and experience comes in. To a true beginner, the space of all possible errors looks like every line in the source code. You don't have the vision you will later develop to see the other dimensions of the program, such as the space of executed lines, the data structure, the memory management, the interaction with foreign code, the code that is risky, and the code that is simple. For the experienced programmer, these other dimensions form an imperfect but very useful mental model of all the things that can go wrong. Having that mental model is what helps one find the middle of the mystery effectively. Once you have evenly subdivided the space of all that can go wrong, you must try to decide in which space the error lies. In the simple case where the mystery is: ‘Which single unknown line makes my program crash?’, you can ask yourself: ‘Is the unknown line executed before or after this line that I judge to be executed in the middle of the running program?’ Usually you will not be so lucky as to know that the error exists in a single line, or even a single block. Often the mystery will be more like: ‘Either there is a pointer in that graph that points to the wrong node, or my algorithm that adds up the variables in that graph doesn't work.’ In that case you may have to write a small program to check that the pointers in the graph are all correct in order to decide which part of the subdivided mystery can be eliminated. -Next [How to Remove an Error](03-How to Remove an Error.md) +Next [How to Remove an Error](03-How-to-Remove-an-Error.md) diff --git a/1-Beginner/Personal-Skills/03-How to Remove an Error.md b/en/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md similarity index 95% rename from 1-Beginner/Personal-Skills/03-How to Remove an Error.md rename to en/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md index 8edb6b1..cf286c0 100644 --- a/1-Beginner/Personal-Skills/03-How to Remove an Error.md +++ b/en/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -1,9 +1,9 @@ # How to Remove an Error - +[//]: # (Version:1.0.0) I've intentionally separated the act of examining a program's execution from the act of fixing an error. But of course, debugging does also mean removing the bug. Ideally you will have perfect understanding of the code and will reach an ‘A-Ha!’ moment where you perfectly see the error and how to fix it. But since your program will often use insufficiently documented systems into which you have no visibility, this is not always possible. In other cases the code is so complicated that your understanding cannot be perfect. In fixing a bug, you want to make the smallest change that fixes the bug. You may see other things that need improvement; but don't fix those at the same time. Attempt to employ the scientific method of changing one thing and only one thing at a time. The best process for this is to be able to easily reproduce the bug, then put your fix in place, and then rerun the program and observe that the bug no longer exists. Of course, sometimes more than one line must be changed, but you should still conceptually apply a single atomic change to fix the bug. Sometimes, there are really several bugs that look like one. It is up to you to define the bugs and fix them one at a time. Sometimes it is unclear what the program should do or what the original author intended. In this case, you must exercise your experience and judgment and assign your own meaning to the code. Decide what it should do, and comment it or clarify it in some way and then make the code conform to your meaning. This is an intermediate or advanced skill that is sometimes harder than writing the original function in the first place, but the real world is often messy. You may have to fix a system you cannot rewrite. -Next [How to Debug Using a Log](04-How to Debug Using a Log.md) \ No newline at end of file +Next [How to Debug Using a Log](04-How-to-Debug-Using-a-Log.md) \ No newline at end of file diff --git a/1-Beginner/Personal-Skills/04-How to Debug Using a Log.md b/en/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md similarity index 69% rename from 1-Beginner/Personal-Skills/04-How to Debug Using a Log.md rename to en/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md index 320c45a..8263ea7 100644 --- a/1-Beginner/Personal-Skills/04-How to Debug Using a Log.md +++ b/en/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -1,13 +1,13 @@ # How to Debug Using a Log - -*Logging* is the practice of writing a system so that it produces a sequence of informative records, called a log. *Printlining* is just producing a simple, usually temporary, log. Absolute beginners must understand and use logs because their knowledge of the programming is limited; system architects must understand and use logs because of the complexity of the system. The amount of information that is provided by the log should be configurable, ideally while the program is running. In general, logs offer three basic advantages: +[//]: # (Version:1.0.0) +*Logging* is the practice of writing a system so that it produces a sequence of informative records, called a log. *Printlining* is just producing a simple, usually temporary, log. Absolute beginners must understand and use logs because their knowledge of programming is limited; system architects must understand and use logs because of the complexity of the system. The amount of information that is provided by the log should be configurable, ideally while the program is running. In general, logs offer three basic advantages: - Logs can provide useful information about bugs that are hard to reproduce (such as those that occur in the production environment but that cannot be reproduced in the test environment). - Logs can provide statistics and data relevant to performance, such as the time passing between statements. - When configurable, logs allow general information to be captured in order to debug unanticipated specific problems without having to modify and/or redeploy the code just to deal with those specific problems. -The amount to output into the log is always a compromise between information and brevity. Too much information makes the log expensive and produces *scroll blindness*, making it hard to find the information you need. Too little information and it may not contain what you need. For this reason, making what is output configurable is very useful. Typically, each record in the log will identify its position in the source code, the thread that executed it if applicable, the precise time of execution, and, commonly, an additional useful piece of information, such as the value of some variable, the amount of free memory, the number of data objects, etc. These log statements are sprinkled throughout the source code but are particularly at major functionality points and around risky code. Each statement can be assigned a level and will only output a record if the system is currently configured to output that level. You should design the log statements to address problems that you anticipate. Anticipate the need to measure performance. +The amount to output into the log is always a compromise between information and brevity. Too much information makes the log expensive and produces *scroll blindness*, making it hard to find the information you need. Too little information and it may not contain what you need. For this reason, making what is output configurable is very useful. Typically, each record in the log will identify its position in the source code, the thread that executed it if applicable, the precise time of execution, and, commonly, an additional useful piece of information, such as the value of some variable, the amount of free memory, the number of data objects, etc. These log statements are sprinkled throughout the source code, particularly at major functionality points and around risky code. Each statement can be assigned a level and will only output a record if the system is currently configured to output that level. You should design the log statements to address problems that you anticipate. Anticipate the need to measure performance. If you have a permanent log, printlining can now be done in terms of the log records, and some of the debugging statements will probably be permanently added to the logging system. -Next [How to Understand Performance Problems](05-How to Understand Performance Problems.md) \ No newline at end of file +Next [How to Understand Performance Problems](05-How-to-Understand-Performance-Problems.md) diff --git a/1-Beginner/Personal-Skills/05-How to Understand Performance Problems.md b/en/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md similarity index 95% rename from 1-Beginner/Personal-Skills/05-How to Understand Performance Problems.md rename to en/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md index e08f054..7a5160f 100644 --- a/1-Beginner/Personal-Skills/05-How to Understand Performance Problems.md +++ b/en/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -1,5 +1,5 @@ # How to Understand Performance Problems - +[//]: # (Version:1.0.0) Learning to understand the performance of a running system is unavoidable for the same reason that learning debugging is. Even if you understand perfectly precisely the cost of the code you write, your code will make calls into other software systems that you have little control over or visibility into. However, in practice performance problems are a little different and a little easier than debugging in general. Suppose that you or your customers consider a system or a subsystem to be too slow. Before you try to make it faster, you must build a mental model of why it is slow. To do this you can use a profiling tool or a good log to figure out where the time or other resources are really being spent. There is a famous dictum that 90% of the time will be spent in 10% of the code. I would add to that the importance of input/output expense (I/O) to performance issues. Often most of the time is spent in I/O in one way or another. Finding the expensive I/O and the expensive 10% of the code is a good first step to building your mental model. @@ -8,4 +8,4 @@ There are many dimensions to the performance of a computer system, and many reso Contention for shared resources that are synchronized can cause deadlock and starvation. Deadlock is the inability to proceed because of improper synchronization or resource demands. Starvation is the failure to schedule a component properly. If it can be at all anticipated, it is best to have a way of measuring this contention from the start of your project. Even if this contention does not occur, it is very helpful to be able to assert that with confidence. -Next [How to Fix Performance Problems](06-How to Fix Performance Problems.md) +Next [How to Fix Performance Problems](06-How-to-Fix-Performance-Problems.md) diff --git a/1-Beginner/Personal-Skills/06-How to Fix Performance Problems.md b/en/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md similarity index 96% rename from 1-Beginner/Personal-Skills/06-How to Fix Performance Problems.md rename to en/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md index 8949e74..7d07f20 100644 --- a/1-Beginner/Personal-Skills/06-How to Fix Performance Problems.md +++ b/en/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -1,5 +1,5 @@ # How to Fix Performance Problems - +[//]: # (Version:1.0.0) Most software projects can be made with relatively little effort 10 to 100 times faster than they are at the time they are first released. Under time-to-market pressure, it is both wise and effective to choose a solution that gets the job done simply and quickly, but less efficiently than some other solution. However, performance is a part of usability, and often it must eventually be considered more carefully. The key to improving the performance of a very complicated system is to analyse it well enough to find the *bottlenecks*, or places where most of the resources are consumed. There is not much sense in optimizing a function that accounts for only 1% of the computation time. As a rule of thumb you should think carefully before doing anything unless you think it is going to make the system or a significant part of it at least twice as fast. There is usually a way to do this. Consider the test and quality assurance effort that your change will require. Each change brings a test burden with it, so it is much better to have a few big changes. @@ -10,4 +10,4 @@ Often, the bottlenecks in performance will be an example of counting cows by cou What do you do when you start to run out of low-hanging fruit? Well, you can reach higher, or chop the tree down. You can continue making small improvements or you can seriously redesign a system or a subsystem. (This is a great opportunity to use your skills as a good programmer, not only in the new design but also in convincing your boss that this is a good idea.) However, before you argue for the redesign of a subsystem, you should ask yourself whether or not your proposal will make it five to ten time better. -Next [How to Optimize Loops](07-How to Optimize Loops.md) +Next [How to Optimize Loops](07-How-to-Optimize-Loops.md) diff --git a/1-Beginner/Personal-Skills/07-How to Optimize Loops.md b/en/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md similarity index 92% rename from 1-Beginner/Personal-Skills/07-How to Optimize Loops.md rename to en/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md index 491a6b2..c3d0078 100644 --- a/1-Beginner/Personal-Skills/07-How to Optimize Loops.md +++ b/en/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -1,5 +1,5 @@ # How to Optimize Loops - +[//]: # (Version:1.0.0) Sometimes you'll encounter loops, or recursive functions, that take a long time to execute and are bottlenecks in your product. Before you try to make the loop a little faster, spend a few minutes considering if there is a way to remove it entirely. Would a different algorithm do? Could you compute that while computing something else? If you can't find a way around it, then you can optimize the loop. This is simple; move stuff out. In the end, this will require not only ingenuity but also an understanding of the expense of each kind of statement and expression. Here are some suggestions: - Remove floating point operations. @@ -12,4 +12,4 @@ Sometimes you'll encounter loops, or recursive functions, that take a long time The cost of each of these operations depends on your specific system. On some systems compilers and hardware do these things for you. Clear, efficient code is better than code that requires an understanding of a particular platform. -Next [How to Deal with I/O Expense](08-How to Deal with IO Expense.md) +Next [How to Deal with I/O Expense](08-How-to-Deal-with-IO-Expense.md) diff --git a/1-Beginner/Personal-Skills/08-How to Deal with IO Expense.md b/en/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md similarity index 95% rename from 1-Beginner/Personal-Skills/08-How to Deal with IO Expense.md rename to en/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md index f396d5b..3a5c127 100644 --- a/1-Beginner/Personal-Skills/08-How to Deal with IO Expense.md +++ b/en/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -1,5 +1,5 @@ # How to Deal with I/O Expense - +[//]: # (Version:1.0.0) For a lot of problems, processors are fast compared to the cost of communicating with a hardware device. This cost is usually abbreviated I/O, and can include network cost, disk I/O, database queries, file I/O, and other use of some hardware not very close to the processor. Therefore building a fast system is often more a question of improving I/O than improving the code in some tight loop, or even improving an algorithm. There are two very fundamental techniques to improving I/O: caching and representation. Caching is avoiding I/O (generally avoiding the reading of some abstract value) by storing a copy of that value locally so no I/O is performed to get the value. The first key to caching is to make it crystal clear which data is the master and which are copies. There is only one master - period. Caching brings with it the danger that the copy sometimes can't reflect changes to the master instantaneously. @@ -10,4 +10,4 @@ Representations can often be improved by a factor of two or three from their fir A third technique that is sometimes possible is to improve the locality of reference by pushing the computation closer to the data. For instance, if you are reading some data from a database and computing something simple from it, such as a summation, try to get the database server to do it for you. This is highly dependent on the kind of system you're working with, but you should explore it. -Next [How to Manage Memory](09-How to Manage Memory.md) \ No newline at end of file +Next [How to Manage Memory](09-How-to-Manage-Memory.md) \ No newline at end of file diff --git a/1-Beginner/Personal-Skills/09-How to Manage Memory.md b/en/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md similarity index 93% rename from 1-Beginner/Personal-Skills/09-How to Manage Memory.md rename to en/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md index a20adf4..7734f72 100644 --- a/1-Beginner/Personal-Skills/09-How to Manage Memory.md +++ b/en/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -1,5 +1,5 @@ # How to Manage Memory - +[//]: # (Version:1.0.0) Memory is a precious resource that you can't afford to run out of. You can ignore it for a while but eventually you will have to decide how to manage memory. Space that needs to persist beyond the scope of a single subroutine is often called *heap allocated*. A chunk of memory is useless, hence *garbage*, when nothing refers to it. Depending on the system you use, you may have to explicitly deallocate memory yourself when it is about to become garbage. More often you may be able to use a system that provides a *garbage collector*. A garbage collector notices garbage and frees its space without any action required by the programmer. Garbage collection is wonderful: it lessens errors and increases code brevity and concision cheaply. Use it when you can. @@ -10,6 +10,6 @@ The creation of new objects is moderately expensive on any system. Memory alloca An important case occurs when you can define an upper bound on the number of objects you will need at one time. If these objects all take up the same amount of memory, you may be able to allocate a single block of memory, or a buffer, to hold them all. The objects you need can be allocated and released inside this buffer in a set rotation pattern, so it is sometimes called a ring buffer. This is usually faster than heap allocation. -Sometimes you have to explicitly free allocated space so it can be reallocated rather than rely on garbage collection. Then you must apply careful intelligence to each chunk of allocated memory and design a way for it to be deallocated at the appropriate time. The method may differ for each kind of object you create. You must make sure that every execution of a memory allocating operation is matched by a memory deallocating operation eventually. This is so difficult that programmers often simply implement a rudimentary form or garbage collection, such as reference counting, to do this for them. +Sometimes you have to explicitly free allocated space so it can be reallocated rather than rely on garbage collection. Then you must apply careful intelligence to each chunk of allocated memory and design a way for it to be deallocated at the appropriate time. The method may differ for each kind of object you create. You must make sure that every execution of a memory allocating operation is matched by a memory deallocating operation eventually. This is so difficult that programmers often simply implement a rudimentary form of garbage collection, such as reference counting, to do this for them. -Next [How to Deal with Intermittent Bugs](10-How to Deal with Intermittent Bugs.md) \ No newline at end of file +Next [How to Deal with Intermittent Bugs](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/1-Beginner/Personal-Skills/10-How to Deal with Intermittent Bugs.md b/en/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md similarity index 70% rename from 1-Beginner/Personal-Skills/10-How to Deal with Intermittent Bugs.md rename to en/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md index 4108f58..10fc692 100644 --- a/1-Beginner/Personal-Skills/10-How to Deal with Intermittent Bugs.md +++ b/en/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -1,8 +1,8 @@ # How to Deal with Intermittent Bugs - +[//]: # (Version:1.0.0) The intermittent bug is a cousin of the 50-foot-invisible-scorpion-from-outer-space kind of bug. This nightmare occurs so rarely that it is hard to observe, yet often enough that it can't be ignored. You can't debug because you can't find it. -Although after 8 hours you will start to doubt it, the intermittent bug has to obey the same laws of logic everything else does. What makes it hard is that it occurs only under unknown conditions. Try to record the circumstances under which the bug does occur, so that you can guess at what the variability really is. The condition may be related to data values, such as ‘This only happens when we enter *Wyoming* as a value.’ If that is not the source of variability, the next suspect should be improperly synchronized concurrency. +Although after 8 hours you will start to doubt it, the intermittent bug has to obey the same laws of logic everything else does. What makes it hard is that it occurs only under unknown conditions. Try to record the circumstances under which the bug does occur, so that you can guess what the variability really is. The condition may be related to data values, such as ‘This only happens when we enter *Wyoming* as a value.’ If that is not the source of variability, the next suspect should be improperly synchronized concurrency. Try, try, try to reproduce the bug in a controlled way. If you can't reproduce it, set a trap for it by building a logging system, a special one if you have to, that can log what you guess you need when it really does occur. Resign yourself to that if the bug only occurs in production and not at your whim, this may be a long process. The hints that you get from the log may not provide the solution but may give you enough information to improve the logging. The improved logging system may take a long time to be put into production. Then, you have to wait for the bug to reoccur to get more information. This cycle can go on for some time. @@ -10,8 +10,8 @@ The stupidest intermittent bug I ever created was in a multi-threaded implementa At work we recently had an intermittent bug that took us several weeks to find. We have multi-threaded application servers in Java™ behind Apache™ web servers. To maintain fast page turns, we do all I/O in small set of four separate threads that are different than the page-turning threads. Every once in a while these would apparently get ‘stuck’ and cease doing anything useful, so far as our logging allowed us to tell, for hours. Since we had four threads, this was not in itself a giant problem - unless all four got stuck. Then the queues emptied by these threads would quickly fill up all available memory and crash our server. It took us about a week to figure this much out, and we still didn't know what caused it, when it would happen, or even what the threads where doing when they got ‘stuck’. -This illustrates some risk associated with third-party software. We were using a licensed piece of code that removed HTML tags from text. Due to its place of origin we affectionately referred to this as ‘the French stripper‘. Although we had the source code (thank goodness!) we had not studied it carefully until by turning up the logging on our servers we finally realized that the email threads were getting stuck in the French stripper. +This illustrates some risk associated with third-party software. We were using a licensed piece of code that removed HTML tags from text. Although we had the source code (thank goodness!) we had not studied it carefully until by turning up the logging on our servers we finally realized that the email threads were getting stuck in this problematic licensed code. -The stripper performed well except on some long and unusual kinds of texts. On these texts, the code was quadratic or worse. This means that the processing time was proportional to the square of the length of the text. Had these texts occurred commonly, we would have found the bug right away. If they had never occurred at all, we would never have had a problem. As it happens, it took us weeks to finally understand and resolve the problem. +The program performed well except on some long and unusual kinds of texts. On these texts, the code was quadratic or worse. This means that the processing time was proportional to the square of the length of the text. Had these texts occurred commonly, we would have found the bug right away. If they had never occurred at all, we would never have had a problem. As it happens, it took us weeks to finally understand and resolve the problem. -Next [How to Learn Design Skills](11-How to Learn Design Skills.md) +Next [How to Learn Design Skills](11-How-to-Learn-Design-Skills.md) diff --git a/1-Beginner/Personal-Skills/11-How to Learn Design Skills.md b/en/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md similarity index 91% rename from 1-Beginner/Personal-Skills/11-How to Learn Design Skills.md rename to en/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md index 30c495c..3ed45bc 100644 --- a/1-Beginner/Personal-Skills/11-How to Learn Design Skills.md +++ b/en/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -1,9 +1,9 @@ # How to Learn Design Skills - +[//]: # (Version:1.0.0) To learn how to design software, study the action of a mentor by being physically present when they are designing. Then study well-written pieces of software. After that, you can read some books on the latest design techniques. Then you must do it yourself. Start with a small project. When you are finally done, consider how the design failed or succeeded and how you diverged from your original conception. Then move on to larger projects, hopefully in conjunction with other people. Design is a matter of judgement that takes years to acquire. A smart programmer can learn the basics adequately in two months and can improve from there. It is natural and helpful to develop your own style, but remember that design is an art, not a science. People who write books on the subject have a vested interest in making it seem scientific. Don't become dogmatic about particular design styles. -Next [How to Conduct Experiments](12-How to Conduct Experiments.md) +Next [How to Conduct Experiments](12-How-to-Conduct-Experiments.md) diff --git a/1-Beginner/Personal-Skills/12-How to Conduct Experiments.md b/en/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md similarity index 94% rename from 1-Beginner/Personal-Skills/12-How to Conduct Experiments.md rename to en/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md index eb1d545..1358296 100644 --- a/1-Beginner/Personal-Skills/12-How to Conduct Experiments.md +++ b/en/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -1,5 +1,5 @@ # How to Conduct Experiments - +[//]: # (Version:1.0.0) The late, great Edsger Dijkstra has eloquently explained that Computer Science is not an experimental science[ExpCS] and doesn't depend on electronic computers. As he puts it referring to the 1960s [Knife], > ...the harm was done: the topic became known as “computer science” - which, actually, is like referring to surgery as “knife science” - and it was firmly implanted in people's minds that computing science is about machines and their peripheral equipment. @@ -10,7 +10,7 @@ The kinds of experiments you will have to perform include: - Testing systems with small examples to verify that they conform to the documentation or to understand their response when there is no documentation, - Testing small code changes to see if they actually fix a bug, -- Measuring the performance of a system under two different conditions due to imperfect knowledge of there performance characteristics, +- Measuring the performance of a system under two different conditions due to imperfect knowledge of their performance characteristics, - Checking the integrity of data, and - Collecting statistics that may hint at the solution to difficult or hard-to-repeat bugs. @@ -20,4 +20,4 @@ First, try to be very clear about your hypothesis, or the assertion that you are You will often find yourself having to design a series of experiments, each of which is based on the knowledge gained from the last experiment. Therefore, you should design your experiments to provide the most information possible. Unfortunately, this is in tension with keeping each experiment simple - you will have to develop this judgement through experience. -Next [Team Skills - Why Estimation is Important](../Team-Skills/01-Why Estimation is Important.md) \ No newline at end of file +Next [Team Skills - Why Estimation is Important](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/en/1-Beginner/README.md b/en/1-Beginner/README.md new file mode 100644 index 0000000..d07cad2 --- /dev/null +++ b/en/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. Beginner +[//]: # (Version:1.0.0) +- Personal Skills + - [Learn to Debug](Personal-Skills/01-Learn-To-Debug.md) + - [How to Debug by Splitting the Problem Space](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [How to Remove an Error](Personal-Skills/03-How-to-Remove-an-Error.md) + - [How to Debug Using a Log](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [How to Understand Performance Problems](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [How to Fix Performance Problems](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [How to Optimize Loops](Personal-Skills/07-How-to-Optimize-Loops.md) + - [How to Deal with I/O Expense](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [How to Manage Memory](Personal-Skills/09-How-to-Manage-Memory.md) + - [How to Deal with Intermittent Bugs](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [How to Learn Design Skills](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [How to Conduct Experiments](Personal-Skills/12-How-to-Conduct-Experiments.md) +- Team Skills + - [Why Estimation is Important](Team-Skills/01-Why-Estimation-is-Important.md) + - [How to Estimate Programming Time](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [How to Find Out Information](Team-Skills/03-How-to-Find-Out-Information.md) + - [How to Utilize People as Information Sources](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [How to Document Wisely](Team-Skills/05-How-to-Document-Wisely.md) + - [How to Work with Poor Code](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [How to Use Source Code Control](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [How to Unit Test](Team-Skills/08-How-to-Unit-Test.md) + - [Take Breaks when Stumped](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [How to Recognize When to Go Home](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [How to Deal with Difficult People](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/1-Beginner/Team-Skills/01-Why Estimation is Important.md b/en/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md similarity index 92% rename from 1-Beginner/Team-Skills/01-Why Estimation is Important.md rename to en/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md index 39ffba8..b24dfec 100644 --- a/1-Beginner/Team-Skills/01-Why Estimation is Important.md +++ b/en/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -1,5 +1,5 @@ # Why Estimation is Important - +[//]: # (Version:1.0.0) To get a working software system in active use as quickly as possible requires not only planning the development, but also planning the documentation, deployment, and marketing. In a commercial project it also requires sales and finance. Without predictability of the development time, it is impossible to plan these effectively. Good estimation provides predictability. Managers love it, as well they should. The fact that it is impossible, both theoretically and practically, to predict accurately how long it will take to develop software is often lost on managers. We are asked to do this impossible thing all the time, and we must face up to it honestly. However, it would be dishonest not to admit the impossibility of this task, and when necessary, explain it. There is a lot of room for miscommunication about estimates, as people have a startling tendency to think wishfully that the sentence: @@ -12,4 +12,4 @@ really means: This common interpretation problem requires that you explicitly discuss what the estimate means with your boss or customer as if they were a simpleton. Restate your assumptions, no matter how obvious they seem to you. -Next [How to Estimate Programming Time](02-How to Estimate Programming Time.md) +Next [How to Estimate Programming Time](02-How-to-Estimate-Programming-Time.md) diff --git a/1-Beginner/Team-Skills/02-How to Estimate Programming Time.md b/en/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md similarity index 80% rename from 1-Beginner/Team-Skills/02-How to Estimate Programming Time.md rename to en/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md index b9be737..f1385ad 100644 --- a/1-Beginner/Team-Skills/02-How to Estimate Programming Time.md +++ b/en/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -1,5 +1,5 @@ # How to Estimate Programming Time - +[//]: # (Version:1.0.0) Estimation takes practice. It also takes labour. It takes so much labour it may be a good idea to estimate the time it will take to make the estimate, especially if you are asked to estimate something big. When asked to provide an estimate of something big, the most honest thing to do is to stall. Most engineers are enthusiastic and eager to please, and stalling certainly will displease the stalled. But an on-the-spot estimate probably won't be accurate and honest. @@ -10,7 +10,7 @@ When not possible to take the time for some investigation, you should first esta I know good engineers who pad estimates implicitly, but I recommend that you do not. One of the results of padding is trust in you may be depleted. For instance, an engineer might estimate three days for a task that she truly thinks will take one day. The engineer may plan to spend two days documenting it, or two days working on some other useful project. But it will be detectable that the task was done in only one day (if it turns out that way), and the appearance of slacking or overestimating is born. It's far better to give proper visibility into what you are actually doing. If documentation takes twice as long as coding and the estimate says so, tremendous advantage is gained by making this visible to the manager. -Pad explicitly instead. If a task will probably take one day - but might take ten days if your approach doesn't work - note this somehow in the estimate if you can; if not, at least do an average weighted by your estimates of the probabilities. Any risk factor that you can identify and assign an estimate to should go into the schedule. One person is unlikely to be sick in any given week. But a large project with many engineers will have some sick time; likewise vacation time. And what is the probability of a mandatory company-wide training seminar? If it can be estimated, stick it in. There are of course, unknown unknowns, or *unk-unks*. Unk-unks by definition cannot be estimated individually. You can try to create a global line item for all unk-unks, or handle them in some other way that you communicate to your boss. You cannot, however, let your boss forget that they exist, and it is devilishly easy for an estimate to become a schedule without the unk-unks considered. +Pad explicitly instead. If a task will probably take one day - but might take ten days if your approach doesn't work - note this somehow in the estimate if you can; if not, at least do an average weighted by your estimates of the probabilities. Any risk factor that you can identify and assign an estimate to, should go into the schedule. One person is unlikely to be sick in any given week. But a large project with many engineers will have some sick time; likewise vacation time. And what is the probability of a mandatory company-wide training seminar? If it can be estimated, stick it in. There are of course, unknown unknowns, or *unk-unks*. Unk-unks by definition cannot be estimated individually. You can try to create a global line item for all unk-unks, or handle them in some other way that you communicate to your boss. You cannot, however, let your boss forget that they exist, and it is devilishly easy for an estimate to become a schedule without the unk-unks considered. In a team environment, you should try to have the people who will do the work do the estimate, and you should try to have team-wide consensus on estimates. People vary widely in skill, experience, preparedness, and confidence. Calamity strikes when a strong programmer estimates for herself and then weak programmers are held to this estimate. The act of having the whole team agree on a line-by-line basis to the estimate clarifies the team understanding, as well as allowing the opportunity for tactical reassignment of resources (for instance, shifting burden away from weaker team members to stronger). @@ -18,4 +18,4 @@ If there are big risks that cannot be evaluated, it is your duty to state so for If you can convince your company to use *Extreme Programming*, you will only have to estimate relatively small things, and this is both more fun and more productive. -Next [How to Find Out Information](03-How to Find Out Information.md) \ No newline at end of file +Next [How to Find Out Information](03-How-to-Find-Out-Information.md) diff --git a/1-Beginner/Team-Skills/03-How to Find Out Information.md b/en/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md similarity index 95% rename from 1-Beginner/Team-Skills/03-How to Find Out Information.md rename to en/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md index b1f0e45..07de694 100644 --- a/1-Beginner/Team-Skills/03-How to Find Out Information.md +++ b/en/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -1,5 +1,5 @@ # How to Find Out Information - +[//]: # (Version:1.0.0) The nature of what you need to know determines how you should find it. If you need information *about concrete things* that are objective and easy to verify, for example the latest patch level of a software product, ask a large number of people politely by searching the internet for it or by posting on a discussion group. Don't search on the internet for anything that smacks of either opinion or subjective interpretation: the ratio of drivel to truth is too high. @@ -16,4 +16,4 @@ If you want to know *how likely it is* that a faster algorithm for a particular If you want to make a *personal decision that only you can make* like whether or not you should start a business, try putting into writing a list of arguments for and against the idea. If that fails, consider divination. Suppose you have studied the idea from all angles, have done all your homework, and worked out all the consequences and pros and cons in your mind, and yet still remain indecisive. You now must follow your heart and tell your brain to shut up. The multitude of available divination techniques are very useful for determining your own semi-conscious desires, as they each present a complete ambiguous and random pattern that your own subconscious will assign meaning to. -Next [How to Utilize People as Information Sources](04-How to Utilize People as Information Sources.md) +Next [How to Utilize People as Information Sources](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/1-Beginner/Team-Skills/04-How to Utilize People as Information Sources.md b/en/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md similarity index 97% rename from 1-Beginner/Team-Skills/04-How to Utilize People as Information Sources.md rename to en/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md index f62a077..0de2a3f 100644 --- a/1-Beginner/Team-Skills/04-How to Utilize People as Information Sources.md +++ b/en/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -1,5 +1,5 @@ # How to Utilize People as Information Sources - +[//]: # (Version:1.0.0) Respect every person's time and balance it against your own. Asking someone a question accomplishes far more than just receiving the answer. The person learns about you, both by enjoying your presence and hearing the particular question. You learn about the person in the same way, and you may learn the answer you seek. This is usually far more important than your question. However, the value of this diminishes the more you do it. You are, after all, using the most precious commodity a person has: their time. The benefits of communication must be weighed against the costs. Furthermore, the particular costs and benefits derived differ from person to person. I strongly believe that an executive of 100 people should spend five minutes a month talking to each person in her organization, which would be about 5% of their time. But ten minutes might be too much, and five minutes is too much if they have one thousand employees. The amount of time you spend talking to each person in your organization depends on their role (more than their position). You should talk to your boss more than your boss's boss, but you should talk to your boss's boss a little. It may be uncomfortable, but I believe you have a duty to talk a little bit to all your superiors, each month, no matter what. @@ -12,4 +12,4 @@ A strange example of this is the summer intern. A summer intern in a highly tech You should ask people for a little bit of their wisdom and judgement whenever you honestly believe they have something to say. This flatters them and you will learn something and teach them something. A good programmer does not often need the advice of a Vice President of Sales, but if you ever do, you be sure to ask for it. I once asked to listen in on a few sales calls to better understand the job of our sales staff. This took no more than 30 minutes but I think that small effort made an impression on the sales force. -Next [How to Document Wisely](05-How to Document Wisely.md) \ No newline at end of file +Next [How to Document Wisely](05-How-to-Document-Wisely.md) \ No newline at end of file diff --git a/1-Beginner/Team-Skills/05-How to Document Wisely.md b/en/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md similarity index 96% rename from 1-Beginner/Team-Skills/05-How to Document Wisely.md rename to en/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md index 895062f..5a7fcad 100644 --- a/1-Beginner/Team-Skills/05-How to Document Wisely.md +++ b/en/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -1,5 +1,5 @@ # How to Document Wisely - +[//]: # (Version:1.0.0) Life is too short to write crap nobody will read; if you write crap, nobody will read it. Therefore a little good documentation is best. Managers often don't understand this, because even bad documentation gives them a false sense of security that they are not dependent on their programmers. If someone absolutely insists that you write truly useless documentation, say 'yes' and quietly begin looking for a better job. There's nothing quite as effective as putting an accurate estimate of the amount of time it will take to produce good documentation into an estimate to slacken the demand for documentation. The truth is cold and hard: documentation, like testing, can take many times longer than developing code. @@ -17,4 +17,4 @@ This does not make it easier on the responsible programmer. How does one write s - Thinking about the reader and spending some of your precious time to make it easier on her; and - Not ever using a function name like `foo`,`bar`, or `doIt`! -Next [How to Work with Poor Code](06-How to Work with Poor Code.md) \ No newline at end of file +Next [How to Work with Poor Code](06-How-to-Work-with-Poor-Code.md) \ No newline at end of file diff --git a/1-Beginner/Team-Skills/06-How to Work with Poor Code.md b/en/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md similarity index 95% rename from 1-Beginner/Team-Skills/06-How to Work with Poor Code.md rename to en/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md index 431ce28..ff6f5b0 100644 --- a/1-Beginner/Team-Skills/06-How to Work with Poor Code.md +++ b/en/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -1,5 +1,5 @@ # How to Work with Poor Code - +[//]: # (Version:1.0.0) It is very common to have to work with poor quality code that someone else has written. Don't think too poorly of them, however, until you have walked in their shoes. They may have been asked very consciously to get something done quickly to meet schedule pressure. Regardless, in order to work with unclear code you must understand it. To understand it takes learning time, and that time will have to come out of some schedule, somewhere, and you must insist on it. To understand it, you will have to read the source code. You will probably have to experiment with it. This is a good time to document, even if it is only for yourself, because the act of trying to document the code will force you to consider angles you might not have considered, and the resulting document may be useful. While you're doing this, consider what it would take to rewrite some or all of the code. Would it actually save time to rewrite some of it? Could you trust it better if you rewrote it? Be careful of arrogance here. If you rewrite it, it will be easier for you to deal with, but will it really be easier for the next person who has to read it? If you rewrite it, what will the test burden be? Will the need to re-test it outweigh any benefits that might be gained? @@ -8,4 +8,4 @@ In any estimate that you make for work against code you didn't write, the qualit It is important to remember that abstraction and encapsulation, two of a programmer's best tools, are particularly applicable to lousy code. You may not be able to redesign a large block of code, but if you can add a certain amount of abstraction to it you can obtain some of the benefits of a good design without reworking the whole mess. In particular, you can try to wall off the parts that are particularly bad so that they may be redesigned independently. -Next [How to Use Source Code Control](07-How to Use Source Code Control.md) \ No newline at end of file +Next [How to Use Source Code Control](07-How-to-Use-Source-Code-Control.md) \ No newline at end of file diff --git a/1-Beginner/Team-Skills/07-How to Use Source Code Control.md b/en/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md similarity index 95% rename from 1-Beginner/Team-Skills/07-How to Use Source Code Control.md rename to en/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md index 91dbf5c..e116dbf 100644 --- a/1-Beginner/Team-Skills/07-How to Use Source Code Control.md +++ b/en/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -1,9 +1,9 @@ # How to Use Source Code Control - +[//]: # (Version:1.0.0) Source code control systems (also known as Version Control Systems) let you manage projects effectively. They're very useful for one person and essential for a group. They track all changes in different versions so that no code is ever lost and meaning can be assigned to changes. One can create throw-away and debugging code with confidence with a source code control system, since the code you modify is kept carefully separate from committed, official code that will be shared with the team or released. I was late to appreciate the benefits of source code control systems but now I wouldn't live without one even on a one-person project. Generally they are necessary when you have team working on the same code base. However, they have another great advantage: they encourage thinking about the code as a growing, organic system. Since each change is marked as a new revision with a new name or number, one begins to think of the software as a visibly progressive series of improvements. I think this is especially useful for beginners. A good technique for using a source code control system is to stay within a few days of being up-to-date at all time. Code that can't be finished in a few days is checked in, but in a way that it is inactive and will not be called, and therefore not create any problems for anybody else. Committing a mistake that slows down your team-mates is a serious error; it is often taboo. -Next [How to Unit Test](08-How to Unit Test.md) +Next [How to Unit Test](08-How-to-Unit-Test.md) diff --git a/1-Beginner/Team-Skills/08-How to Unit Test.md b/en/1-Beginner/Team-Skills/08-How-to-Unit-Test.md similarity index 90% rename from 1-Beginner/Team-Skills/08-How to Unit Test.md rename to en/1-Beginner/Team-Skills/08-How-to-Unit-Test.md index c1dc402..d1c8dae 100644 --- a/1-Beginner/Team-Skills/08-How to Unit Test.md +++ b/en/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -1,9 +1,9 @@ # How to Unit Test - +[//]: # (Version:1.0.0) Unit testing, the testing of an individual piece of coded functionality by the team that wrote it, is a part of coding, not something different from it. Part of designing the code is designing how it will be tested. You should write down a test plan, even if it is only one sentence. Sometimes the test will be simple: 'Does the button look good?' Sometimes it will be complex: 'Did this matching algorithm return precisely the correct matches?' Use assertion checking and test drivers whenever possible. This not only catches bugs early, but is very useful later on and lets you eliminate mysteries that you would otherwise have to worry about. The Extreme Programming developers are writing extensively on unit testing effectively; I can do no better than to recommend their writings. -Next [Take Breaks when Stumped](09-Take Breaks when Stumped.md) \ No newline at end of file +Next [Take Breaks when Stumped](09-Take-Breaks-when-Stumped.md) \ No newline at end of file diff --git a/1-Beginner/Team-Skills/09-Take Breaks when Stumped.md b/en/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md similarity index 74% rename from 1-Beginner/Team-Skills/09-Take Breaks when Stumped.md rename to en/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md index c578991..274c682 100644 --- a/1-Beginner/Team-Skills/09-Take Breaks when Stumped.md +++ b/en/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -1,5 +1,5 @@ # Take Breaks when Stumped - +[//]: # (Version:1.0.0) When stumped, take a break. I sometimes meditate for 15 minutes when stumped and the problem magically unravels when I come back to it. A night's sleep sometimes does the same thing on a larger scale. It's possible that temporarily switching to any other activity may work. -Next [How to Recognize When to Go Home](10-How to Recognize When to Go Home.md) \ No newline at end of file +Next [How to Recognize When to Go Home](10-How-to-Recognize-When-to-Go-Home.md) diff --git a/1-Beginner/Team-Skills/10-How to Recognize When to Go Home.md b/en/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md similarity index 87% rename from 1-Beginner/Team-Skills/10-How to Recognize When to Go Home.md rename to en/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md index a6ae9b4..da276e6 100644 --- a/1-Beginner/Team-Skills/10-How to Recognize When to Go Home.md +++ b/en/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -1,6 +1,6 @@ # How to Recognize When to Go Home - -Computer programming is an activity that is also a culture. The unfortunate fact is that it is not a culture that values mental or physical health very much. For both cultural/historical reasons (the need to work at night on unloaded computers, for example) and because of overwhelming time-to-market pressure and the scarcity of programmers, computer programmers are traditionally overworked. I don't think you can trust all the stories you hear, but I think 60 hours a week is common, and 50 is pretty much a minimum. This means that often much more than that is required. This is serious problem for a good programmer, who is responsible not only for themselves but their team-mates as well. You have to recognize when to go home, and sometimes when to suggest that other people go home. There can't be any fixed rules for solving this problem, anymore than there can be fixed rules for raising a child, for the same reason---every human being is different. +[//]: # (Version:1.0.0) +Computer programming is an activity that is also a culture. The unfortunate fact is that it is not a culture that values mental or physical health very much. For both cultural/historical reasons (the need to work at night on unloaded computers, for example) and because of overwhelming time-to-market pressure and the scarcity of programmers, computer programmers are traditionally overworked. I don't think you can trust all the stories you hear, but I think 60 hours a week is common, and 50 is pretty much a minimum. This means that often much more than that is required. This is a serious problem for a good programmer, who is responsible not only for themselves but their team-mates as well. You have to recognize when to go home, and sometimes when to suggest that other people go home. There can't be any fixed rules for solving this problem, anymore than there can be fixed rules for raising a child, for the same reason---every human being is different. Beyond 60 hours a week is an extraordinary effort for me, which I can apply for short periods of time (about one week), and that is sometimes expected of me. I don't know if it is fair to expect 60 hours of work from a person; I don't even know if 40 is fair. I am sure, however, that it is stupid to work so much that you are getting little out of that extra hour you work. For me personally, that's any more than 60 hours a week. I personally think a programmer should exercise noblesse oblige and shoulder a heavy burden. However, it is not a programmer's duty to be a patsy. The sad fact is programmers *are* often asked to be patsies in order to put on a show for somebody, for example a manager trying to impress an executive. Programmers often succumb to this because they are eager to please and not very good at saying no. There are four defences against this: @@ -13,4 +13,4 @@ Most programmers are good programmers, and good programmers want to get a lot do Since I have children, I try to spend evenings with them sometimes. The rhythm that works best for me is to work a very long day, sleep in the office or near the office (I have a long commute from home to work) then go home early enough the next day to spend time with my children before they go to bed. I am not comfortable with this, but it is the best compromise I have been able to work out. Go home if you have a contagious disease. You should go home if you are thinking suicidal thoughts. You should take a break or go home if you think homicidal thoughts for more than a few seconds. You should send someone home if they show serious mental malfunctioning or signs of mental illness beyond mild depression. If you are tempted to be dishonest or deceptive in a way that you normally are not due to fatigue, you should take a break. Don't use cocaine or amphetamines to combat fatigue. Don't abuse caffeine. -Next [How to Deal with Difficult People](11-How to Deal with Difficult People.md) \ No newline at end of file +Next [How to Deal with Difficult People](11-How-to-Deal-with-Difficult-People.md) diff --git a/1-Beginner/Team-Skills/11-How to Deal with Difficult People.md b/en/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md similarity index 66% rename from 1-Beginner/Team-Skills/11-How to Deal with Difficult People.md rename to en/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md index d9678e5..8b98887 100644 --- a/1-Beginner/Team-Skills/11-How to Deal with Difficult People.md +++ b/en/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -1,10 +1,10 @@ # How to Deal with Difficult People - +[//]: # (Version:1.0.0) You will probably have to deal with difficult people. You may even be a difficult person yourself. If you are the kind of person who has a lot of conflicts with co-workers and authority figures, you should cherish the independence this implies, but work on your interpersonal skills without sacrificing your intelligence or principles. -This can be very disturbing to some programmers who have no experience in this sort of thing and whose previous life experience has taught them patterns of behaviour that are not useful in the workplace. Difficult people are often inured to disagreement and they are less affected by social pressure to compromise than others. The key is to respect them appropriately, which is more than you will want to but not as much as they might want. +This can be very disturbing to some programmers who have no experience in this sort of thing and whose previous life experience has taught them patterns of behaviour that are not useful in the workplace. Difficult people are often accustomed to disagreement and they are less affected by social pressure to compromise than others. The key is to respect them appropriately, which is more than you will want to but not as much as they might want. -Programmers have to work together as a team. When disagreement arises, it must be resolved somehow, it cannot be ducked for long. Difficult people are often extremely intelligent and have something very useful to say. It is critical that you listen and understand the difficult person without prejudice caused by the person. A failure to communicate is often the basis of disagreement but it can sometimes be removed with great patience. Try to keep this communication cool and cordial, and don't accept any baits for greater conflict that may be offered. After a reasonable period of trying to understand, make a decision. +Programmers have to work together as a team. When disagreement arises, it must be resolved somehow, it cannot be ducked for long. Difficult people are often extremely intelligent and have something very useful to say. It is critical that you listen to and understand the difficult person without prejudice caused by the person. A failure to communicate is often the basis of disagreement but it can sometimes be removed with great patience. Try to keep this communication cool and cordial, and don't accept any baits for greater conflict that may be offered. After a reasonable period of trying to understand, make a decision. Don't let a bully force you to do something you don't agree with. If you are the leader, do what you think is best. Don't make a decision for any personal reasons, and be prepared to explain the reasons for your decision. If you are a team-mate with a difficult person, don't let the leader's decision have any personal impact. If it doesn't go your way, do it the other way whole-heartedly. @@ -12,4 +12,4 @@ Difficult people do change and improve. I've seen it with my own eyes, but it is One of the challenges that every programmer but especially leaders face is keeping the difficult person fully engaged. They are more prone to duck work and resist passively than others. -Next [Intermediate skills](../../2-Intermediate) \ No newline at end of file +Next [Intermediate skills](../../2-Intermediate) diff --git a/2-Intermediate/Judgment/01-How to Tradeoff Quality Against Development Time.md b/en/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md similarity index 53% rename from 2-Intermediate/Judgment/01-How to Tradeoff Quality Against Development Time.md rename to en/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md index 06eefd2..87f168d 100644 --- a/2-Intermediate/Judgment/01-How to Tradeoff Quality Against Development Time.md +++ b/en/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -1,13 +1,13 @@ # How to Tradeoff Quality Against Development Time - -Software development is always a compromise between what the project does and getting the project done. But you may be asked to tradeoff quality to speed the deployment of a project in a way that offends your engineering sensibilities or business sensibilities. For example, you may be asked to do something that is a poor software engineering practice and that will lead to a lot of maintenance problems. +[//]: # (Version:1.0.0) +Software development is always a compromise between what the project does and getting the project done. But you may be asked to tradeoff quality to speed the deployment of a project in a way that offends your engineering or business sensibilities. For example, you may be asked to do something that is a poor software engineering practice and that will lead to a lot of maintenance problems. If this happens your first responsibility is to inform your team and to clearly explain the cost of the decrease in quality. After all, your understanding of it should be much better than your boss's understanding. Make it clear what is being lost and what is being gained, and at what cost the lost ground will be regained in the next cycle. In this, the visibility provided by a good project plan should be helpful. If the quality tradeoff affects the quality assurance effort, point that out (both to your boss and quality assurance people). If the quality tradeoff will lead to more bugs being reported after the quality assurance period, point that out. -If she still insists you should try to isolate the shoddiness into particular components that you can plan to rewrite or improve in the next cycle. Explain this to your team so that they can plan for it. +If she still insists, you should try to isolate the shoddiness into particular components that you can plan to rewrite or improve in the next cycle. Explain this to your team so that they can plan for it. NinjaProgrammer at Slashdot sent in this gem: -> Remember that a good design will be resillient against poor code implementations. If good interfaces and abstractions exist throughout the code, then the eventual rewrites will be far more painless. If it is hard to write clear code that is hard to fix, consider what is wrong with the core design that is causing this. +> Remember that a good design will be resilient against poor code implementations. If good interfaces and abstractions exist throughout the code, then the eventual rewrites will be far more painless. If it is hard to write clear code that is hard to fix, consider what is wrong with the core design that is causing this. -Next [How to Manage Software Dependence](02-How to Manage Software System Dependence.md) \ No newline at end of file +Next [How to Manage Software Dependence](02-How-to-Manage-Software-System-Dependence.md) diff --git a/2-Intermediate/Judgment/02-How to Manage Software System Dependence.md b/en/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md similarity index 90% rename from 2-Intermediate/Judgment/02-How to Manage Software System Dependence.md rename to en/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md index 0f4c9ba..bfe31fc 100644 --- a/2-Intermediate/Judgment/02-How to Manage Software System Dependence.md +++ b/en/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -1,5 +1,5 @@ # How to Manage Software System Dependence - +[//]: # (Version:1.0.0) Modern software systems tend to depend on a large number of components that may not be directly under your control. This increases productivity through synergy and reuse. However, each component brings with it some problems: - How will you fix bugs in the component? @@ -10,4 +10,4 @@ It is always best to encapsulate the component in some way so that it is isolate Having the source code for a component decreases the risk by a factor of four. With source code, you can evaluate it easier, debug it easier, find workarounds easier, and make fixes easier. If you make fixes, you should give them to the owner of the component and get the fixes incorporated into an official release; otherwise you will uncomfortably have to maintain an unofficial version. -Next [How to Decide if Software is Too Immature](03-How to Decide if Software is Too Immature.md) +Next [How to Decide if Software is Too Immature](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/2-Intermediate/Judgment/03-How to Decide if Software is Too Immature.md b/en/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md similarity index 92% rename from 2-Intermediate/Judgment/03-How to Decide if Software is Too Immature.md rename to en/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md index 3f70316..dca19f3 100644 --- a/2-Intermediate/Judgment/03-How to Decide if Software is Too Immature.md +++ b/en/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -1,5 +1,5 @@ # How to Decide if Software is Too Immature - +[//]: # (Version:1.0.0) Using software other people wrote is one of the most effective ways to quickly build a solid system. It should not be discouraged, but the risks associated with it must be examined. One of the biggest risks is the period of bugginess and near inoperability that is often associated with software before it matures, through usage, into a usable product. Before you consider integrating with a software system, whether created in house or by a third party, it is very important to consider if it is really mature enough to be used. Here are ten questions you should ask yourself about it: 1. Is it vapour? (Promises are very immature). @@ -15,4 +15,4 @@ Using software other people wrote is one of the most effective ways to quickly b A little consideration of these criteria demonstrates the great value of well-established free software and open-source software in reducing risk to the entrepreneur. -Next [How to Make a Buy vs. Build Decision](04-How to Make a Buy vs Build Decision.md) \ No newline at end of file +Next [How to Make a Buy vs. Build Decision](04-How-to-Make-a-Buy-vs-Build-Decision.md) \ No newline at end of file diff --git a/2-Intermediate/Judgment/04-How to Make a Buy vs Build Decision.md b/en/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md similarity index 95% rename from 2-Intermediate/Judgment/04-How to Make a Buy vs Build Decision.md rename to en/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md index 587c532..73c35c0 100644 --- a/2-Intermediate/Judgment/04-How to Make a Buy vs Build Decision.md +++ b/en/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -1,5 +1,5 @@ # How to Make a Buy vs. Build Decision - +[//]: # (Version:1.0.0) An entrepreneurial company or project that is trying to accomplish something with software has to constantly make so-called *buy vs. build* decisions. This turn of phrase is unfortunate in two ways: it seems to ignore open-source and free software which is not necessarily *bought*. Even more importantly, it should perhaps be called an *obtain and integrate vs. build here and integrate* decision because the cost of integration must be considered. This requires a great combination of business, management, and engineering savvy. - How well do your needs match those for which it was designed? @@ -13,4 +13,4 @@ You should think twice before building something that is big enough to serve as After considering these questions, you should perhaps prepare two draft project plans, one for building and one for buying. This will force you to consider the integration costs. You should also consider the long term maintenance costs of both solutions. To estimate the integration costs, you will have to do a thorough evaluation of the software before you buy it. If you can't evaluate it, you will assume an unreasonable risk in buying it and you should decide against buying that particular product. If there are several buy decisions under consideration, some energy will have to be spent evaluating each. -Next [How to Grow Professionally](05-How to Grow Professionally.md) +Next [How to Grow Professionally](05-How-to-Grow-Professionally.md) diff --git a/2-Intermediate/Judgment/05-How to Grow Professionally.md b/en/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md similarity index 91% rename from 2-Intermediate/Judgment/05-How to Grow Professionally.md rename to en/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md index 25ce941..1694e84 100644 --- a/2-Intermediate/Judgment/05-How to Grow Professionally.md +++ b/en/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -1,5 +1,5 @@ # How to Grow Professionally - +[//]: # (Version:1.0.0) Assume responsibility in excess of your authority. Play the role that you desire. Express appreciation for people's contribution to the success of the larger organization, as well as things as that help you personally. If you want to become a team leader, instigate the formation of consensus. If you want to become a manager, take responsibility for the schedule. You can usually do this comfortably while working with a leader or a manager, since this frees them up to take greater responsibility. If that is too much to try, do it a little at a time. @@ -8,4 +8,4 @@ Evaluate yourself. If you want to become a better programmer, ask someone you ad Plan ways to learn new skills, both the trivial technical kind, like learning a new software system, and the hard social kind, like writing well, by integrating them into your work. -Next [How to Evaluate Interviewees](06-How to Evaluate Interviewees.md) \ No newline at end of file +Next [How to Evaluate Interviewees](06-How-to-Evaluate-Interviewees.md) \ No newline at end of file diff --git a/2-Intermediate/Judgment/06-How to Evaluate Interviewees.md b/en/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md similarity index 84% rename from 2-Intermediate/Judgment/06-How to Evaluate Interviewees.md rename to en/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md index 3503adb..43933f4 100644 --- a/2-Intermediate/Judgment/06-How to Evaluate Interviewees.md +++ b/en/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -1,5 +1,5 @@ # How to Evaluate Interviewees - +[//]: # (Version:1.0.0) Evaluating potential employees is not given the energy it deserves. A bad hire, like a bad marriage, is terrible. A significant portion of everyone's energy should be devoted to recruitment, though this is rarely done. There are different interviewing styles. Some are torturous, designed to put the candidate under a great deal of stress. This serves a very valuable purpose of possibly revealing character flaws and weaknesses under stress. Candidates are no more honest with interviewers than they are with themselves, and the human capacity for self-deception is astonishing. @@ -8,8 +8,8 @@ You should, at a minimum, give the candidate the equivalent of an oral examinati In doing this, you should also evaluate their ability to learn, which is far more important than what they know. You should also watch for the whiff of brimstone that is given off by difficult people. You may be able to recognize it by comparing notes after the interview, but in the heat of the interview it is hard to recognize. How well people communicate and work with people is more important than being up on the latest programming language. -A reader has had good luck using a ‘take-home’ test for interviewees. This has the advantage that can uncover the interviewee that can present themselves well but can't really code - and there are many such people. I personally have not tried this technique, but it sounds sensible. +A reader has had good luck using a ‘take-home’ test for interviewees. This has the advantage that it can uncover the interviewee that can present themselves well but can't really code - and there are many such people. I personally have not tried this technique, but it sounds sensible. Finally, interviewing is also a process of selling. You should be selling your company or project to the candidate. However, you are talking to a programmer, so don't try to colour the truth. Start off with the bad stuff, then finish strong with the good stuff. -Next [How to Know When to Apply Fancy Computer Science](07-How to Know When to Apply Fancy Computer Science.md) \ No newline at end of file +Next [How to Know When to Apply Fancy Computer Science](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/2-Intermediate/Judgment/07-How to Know When to Apply Fancy Computer Science.md b/en/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md similarity index 95% rename from 2-Intermediate/Judgment/07-How to Know When to Apply Fancy Computer Science.md rename to en/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md index 0201009..4c9df66 100644 --- a/2-Intermediate/Judgment/07-How to Know When to Apply Fancy Computer Science.md +++ b/en/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -1,5 +1,5 @@ # How to Know When to Apply Fancy Computer Science - +[//]: # (Version:1.0.0) There is a body of knowledge about algorithms, data structures, mathematics, and other gee-whiz stuff that most programmers know about but rarely use. In practice, this wonderful stuff is too complicated and generally unnecessary. There is no point in improving an algorithm when most of your time is spent making inefficient database calls, for instance. An unfortunate amount of programming consists of getting systems to talk to each other and using very simple data structures to build a nice user interface. When is high technology the appropriate technology? When should you crack a book to get something other than a run-of-the-mill algorithm? It is sometimes useful to do this but it should be evaluated carefully. @@ -12,4 +12,4 @@ The three most important considerations for the potential computer science techn If a well-isolated algorithm that uses a slightly fancy algorithm can decrease hardware cost or increase performance by a factor of two across an entire system, then it would be criminal not to consider it. One of the keys to arguing for such an approach is to show that the risk is really quite low, since the proposed technology has probably been well studied, the only issue is the risk of integration. Here a programmer's experience and judgement can truly synergize with the fancy technology to make integration easy. -Next [How to Talk to Non-Engineers](08-How to Talk to Non-Engineers.md) \ No newline at end of file +Next [How to Talk to Non-Engineers](08-How-to-Talk-to-Non-Engineers.md) \ No newline at end of file diff --git a/2-Intermediate/Judgment/08-How to Talk to Non-Engineers.md b/en/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md similarity index 81% rename from 2-Intermediate/Judgment/08-How to Talk to Non-Engineers.md rename to en/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md index 809d459..a2b6211 100644 --- a/2-Intermediate/Judgment/08-How to Talk to Non-Engineers.md +++ b/en/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -1,5 +1,5 @@ # How to Talk to Non-Engineers - +[//]: # (Version:1.0.0) Engineers and programmers in particular are generally recognized by popular culture as being different from other people. This implies that other people are different from us. This is worth bearing in mind when communicating with non-engineers; you should always understand the audience. Non-engineers are smart, but not as grounded in creating technical things as we are. We make things. They sell things and handle things and count things and manage things, but they are not experts on making things. They are not as good at working together on teams as engineers are (there are no doubt exceptions.) Their social skills are generally as good as or better than engineers in non-team environments, but their work does not always demand that they practice the kind of intimate, precise communication and careful subdivisions of tasks that we do. @@ -8,12 +8,12 @@ Non-engineers may be too eager to please and they may be intimidated by you. Jus Non-programmers can understand technical things but they do not have the thing that is so hard even for us - technical judgement. They do understand how technology works, but they cannot understand why a certain approach would take three months and another one three days. (After all, programmers are anecdotally horrible at this kind of estimation as well.) This represents a great opportunity to synergize with them. -When talking to your team you will, without thinking, use a sort of shorthand, an abbreviated language that is effective because you will have much shared experience about technology in general and your product in particular. It takes some effort not to use this shorthand with those that don't have that shared experience, especially when members of your own team are present. This vocabulary create a wall between you and those that do not share it, and, even worse, wastes their time. +When talking to your team you will, without thinking, use a sort of shorthand, an abbreviated language that is effective because you will have much shared experience about technology in general and your product in particular. It takes some effort not to use this shorthand with those that don't have that shared experience, especially when members of your own team are present. This vocabulary creates a wall between you and those that do not share it, and, even worse, wastes their time. -With your team, the basic assumptions and goals do not need to be restated often, and most conversation focuses on the details. With outsiders, it must be the other way around. They may not understand things you take for granted. Since you take them for granted and don't repeat them, you can leave a conversation with an outsider thinking that you understand each other when really there is a large misunderstanding. You should assume that you will miscommunicate and watch carefully to find this miscommunication. Try to get them to summarize or paraphrase what you are saying to make sure they understand. If you have the opportunity to meet with them often, spend a little bit of time asking if you you are communicating effectively, and how you can do it better. If there is a problem in communication, seek to alter your own practices before becoming frustrated with theirs. +With your team, the basic assumptions and goals do not need to be restated often, and most conversation focuses on the details. With outsiders, it must be the other way around. They may not understand things you take for granted. Since you take them for granted and don't repeat them, you can leave a conversation with an outsider thinking that you understand each other when really there is a large misunderstanding. You should assume that you will miscommunicate and watch carefully to find this miscommunication. Try to get them to summarize or paraphrase what you are saying to make sure they understand. If you have the opportunity to meet with them often, spend a little bit of time asking if you are communicating effectively, and how you can do it better. If there is a problem in communication, seek to alter your own practices before becoming frustrated with theirs. I love working with non-engineers. It provides great opportunities to learn and to teach. You can often lead by example, in terms of the clarity of your communication. Engineers are trained to bring order out of chaos, to bring clarity out of confusion, and non-engineers like this about us. Because we have technical judgement and can usually understand business issues, we can often find a simple solution to a problem. -Often non-engineers propose solutions that they think will make it easier on us out of kindness and a desire to do the right thing, when in fact a much better overall solution exists which can only be seen by synergizing the outsiders view with your technical judgement. I personally like Extreme Programming because it addresses this inefficiency; by marrying the estimation quickly to the idea, it makes it easier to find the idea that is the best combination of cost and benefit. +Often non-engineers propose solutions that they think will make it easier on us out of kindness and a desire to do the right thing, when in fact a much better overall solution exists which can only be seen by synergizing the outsider's view with your technical judgement. I personally like Extreme Programming because it addresses this inefficiency; by marrying the estimation quickly to the idea, it makes it easier to find the idea that is the best combination of cost and benefit. -Next [Advanced skills](../../3-Advanced) \ No newline at end of file +Next [Advanced skills](../../3-Advanced) diff --git a/en/2-Intermediate/Mentoring/How-To-Be-Mentored.md b/en/2-Intermediate/Mentoring/How-To-Be-Mentored.md new file mode 100644 index 0000000..6acdf94 --- /dev/null +++ b/en/2-Intermediate/Mentoring/How-To-Be-Mentored.md @@ -0,0 +1,23 @@ +

How to Be Mentored

+ +## Being mentored is a vital component in the growth of a programmer. It accelerates learning, provides guidance, and helps in navigating the complexities of the software and engineering industry. + +### 1. Seek Out the Right Mentor + +- Identify your goals and understand what you aim to achieve to find a mentor whose expertise aligns with your objectives. +- Choose someone whose experience complements your learning needs and with whom you can build a rapport by looking for experience and compatibility. + +### 2. Be Proactive and Engaged +- Take initiative and approach your mentor with specific questions and topics for discussion. +- Show commitment! Demonstrate dedication by actively applying the guidance received and sharing progress. + +### 3. Cultivate Open Communication +- Be receptive to feedback. Embrace constructive criticism as a tool for improvement. +- Understand that your mentor is there to help. +- Acknowledge and appreciation their valuable time and effort to foster a positive mentoring relationship. + +### 4. Reflect and Act +- Regularly assess your development and identify areas needing further attention. +- Apply any insights gained to real-world scenarios to solidify your skills. + +Embracing mentorship with an open and proactive mindset can significantly enhance your programming journey, leading to both personal and professional growth. diff --git a/en/2-Intermediate/Mentoring/How-to-Mentor-Others.md b/en/2-Intermediate/Mentoring/How-to-Mentor-Others.md new file mode 100644 index 0000000..0a56ba5 --- /dev/null +++ b/en/2-Intermediate/Mentoring/How-to-Mentor-Others.md @@ -0,0 +1,20 @@ +

How to Mentor Others

+ +## Being a mentor is a highly reward endeavor that not only aids the mentee but also enriches the mentor's experience. + +### 1. Establish Clear Objectives +- The first step is to understand the mentee's goals. Discuss and align on what they aim to achieve through the mentorship. +- Set Expectations and define the scope, frequency, and mode of interactions to ensure a structured relationship. + +### 2. Create a Supportive Environment +- Encourage questions and create a safe space for the mentee to express learn and doubts without hesitation. +- Be patient and provide consistent support. Recognize that learning is a process. + +### 3. Provide Constructive Feedback +- Offer honest insights that are truthful yet considerate, focusing on growth areas. +- Acknowledge and reinforce the mentee's capabilities to build confidence and highlight their strengths. + +### 4. Encourage Independence +- Guide them to think critically and develop solutions independently, developing valuable problem-solving skills. +- As the mentee grows in experience and knowledge, create autonomy by shifting from directive guidance to a more advisory role. +One method is to request that they to walk you through a task as if you were a beginner. diff --git a/en/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/en/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..0e30198 --- /dev/null +++ b/en/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,15 @@ +# How to Stay Motivated +[//]: # (Version:1.0.0) +It is a wonderful and surprising fact that programmers are highly motivated by the desire to create artifacts that are beautiful, useful or nifty. This desire is not unique to programmers nor universal but it is so strong and common among programmers that it separates them from others in other roles. + +This has practical and important consequences. If programmers are asked to do something that is not beautiful, useful or nifty, they will have low morale. There's a lot of money to be made doing ugly, stupid, and boring stuff; but in the end, fun will make the most money for the company. + +Obviously, there are entire industries organized around motivational techniques, some of which apply here. The things that are specific to programming that I can identify are: + +- Use the best language for the job. +- Look for opportunities to apply new techniques, languages and technologies. +- Try to either learn or teach something, no matter how small, in each project. + +Finally, if possible, measure the impact of your work in terms of something that will be personally motivating. For example, when fixing bugs, counting the number of bugs that I have fixed is not at all motivational to me, because it is independent of the number that may still exist, and it also affects the total value I'm adding to my company's customers in only the smallest possible way. Relating each bug to a happy customer, however, *is* personally motivating to me. + +Next [How to be Widely Trusted](02-How-to-be-Widely-Trusted.md) diff --git a/2-Intermediate/Personal-Skills/02-How to be Widely Trusted.md b/en/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md similarity index 72% rename from 2-Intermediate/Personal-Skills/02-How to be Widely Trusted.md rename to en/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md index d99124d..2ffa3c6 100644 --- a/2-Intermediate/Personal-Skills/02-How to be Widely Trusted.md +++ b/en/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -1,7 +1,7 @@ # How to be Widely Trusted - -To be trusted you must be trustworthy. You must also be visible. If no one knows about you, no trust will be invested in you. With those close to you, such as your teammates, this should not be an issue. You establish trust by being responsive and informative to those outside your department or team. Occasionally someone will abuse this trust, and ask for unreasonable favours. Don't be afraid of this, just explain what you would have to give up doing to perform the favour. +[//]: # (Version:1.0.0) +To be trusted you must be trustworthy. You must also be visible. If no one knows about you, no trust will be invested in you. With those close to you, such as your teammates, this should not be an issue. You establish trust by being responsive and informative to those outside your department or team. Occasionally, someone will abuse this trust and ask for unreasonable favours. Don't be afraid of this, just explain what you would have to give up doing to perform the favour. Don't pretend to know something that you don't. With people that are not teammates, you may have to make a clear distinction between 'not knowing right off the top of my head' and 'not being able to figure it out, ever.' -Next [How to Tradeoff Time vs. Space](03-How to Tradeoff Time vs Space.md) +Next [How to Tradeoff Time vs. Space](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/2-Intermediate/Personal-Skills/03-How to Tradeoff Time vs Space.md b/en/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md similarity index 92% rename from 2-Intermediate/Personal-Skills/03-How to Tradeoff Time vs Space.md rename to en/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md index f31cb83..59add49 100644 --- a/2-Intermediate/Personal-Skills/03-How to Tradeoff Time vs Space.md +++ b/en/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -1,15 +1,15 @@ # How to Tradeoff Time vs. Space - +[//]: # (Version:1.0.0) You can be a good programmer without going to college, but you can't be a good intermediate programmer without knowing basic computational complexity theory. You don't need to know 'big O' notation, but I personally think you should be able to understand the difference between 'constant-time','n log n' and 'n squared'. You might be able to intuit how to trade-off time against space without this knowledge, but in its absence you will not have a firm basis for communicating with your colleagues. In designing or understanding an algorithm, the amount of time it takes to run is sometimes a function of the size of the input. When that is true, we can say an algorithm's worst/expected/best-case running time is 'n log n' if it is proportional to the size ($n$) times the logarithm of the size. The notation and way of speaking can be also be applied to the space taken up by a data structure. To me, computational complexity theory is beautiful and as profound as physics - and a little bit goes a long way! -Time (processor cycles) and space (memory) can be traded off against each other. Engineering is about compromise, and this is a fine example. It is not always systematic. In general, however, one can save space by encoding things more tightly, at the expense of more computation time when you have to decode them. You can save time by caching, that is, spending space to store a local copy of something, at the expense of having to maintain the consistency of the cache. You can sometimes save time by maintaining more information in a data structure. This usually cost a small amount of space but may complicate the algorithm. +Time (processor cycles) and space (memory) can be traded off against each other. Engineering is about compromise, and this is a fine example. It is not always systematic. In general, however, one can save space by encoding things more tightly, at the expense of more computation time when you have to decode them. You can save time by caching, that is, spending space to store a local copy of something, at the expense of having to maintain the consistency of the cache. You can sometimes save time by maintaining more information in a data structure. This usually costs a small amount of space, but may complicate the algorithm. Improving the space/time trade-off can often change one or the other dramatically. However, before you work on this you should ask yourself if what you are improving is really the thing that needs the most improvement. It's fun to work on an algorithm, but you can't let that blind you to the cold hard fact that improving something that is not a problem will not make any noticeable difference and will create a test burden. Memory on modern computers appears cheap, because unlike processor time, you can't see it being used until you hit the wall; but then failure is catastrophic. There are also other hidden costs to using memory, such as your effect on other programs that must be resident, and the time to allocate and deallocate it. Consider this carefully before you trade away space to gain speed. -Next [How to Stress Test](04-How to Stress Test.md) +Next [How to Stress Test](04-How-to-Stress-Test.md) diff --git a/2-Intermediate/Personal-Skills/04-How to Stress Test.md b/en/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md similarity index 95% rename from 2-Intermediate/Personal-Skills/04-How to Stress Test.md rename to en/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md index 901ec92..32f3b79 100644 --- a/2-Intermediate/Personal-Skills/04-How to Stress Test.md +++ b/en/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -1,5 +1,5 @@ # How to Stress Test - +[//]: # (Version:1.0.0) Stress testing is fun. At first it appears that the purpose of stress testing is to find out if the system works under a load. In reality, it is common that the system does work under a load but fails to work in some way when the load is heavy enough. I call this *hitting the wall* or *bonking*[1]. There may be some exceptions, but there is almost always a ‘wall’. The purpose of stress testing is to figure out where the wall is, and then figure out how to move the wall further out. A plan for stress testing should be developed early in the project, because it often helps to clarify exactly what is expected. Is two seconds for a web page request a miserable failure or a smashing success? Is 500 concurrent users enough? That, of course, depends, but one must know the answer when designing the system that answers the request. The stress test needs to model reality well enough to be useful. It isn't really possible to simulate 500 erratic and unpredictable humans using a system concurrently very easily, but one can at least create 500 simulations and try to model some part of what they might do. @@ -14,4 +14,4 @@ Knowing where the wall is is essential not only to moving the wall, but also to [1] "to hit" -Next [How to Balance Brevity and Abstraction](05-How to Balance Brevity and Abstraction.md) \ No newline at end of file +Next [How to Balance Brevity and Abstraction](05-How-to-Balance-Brevity-and-Abstraction.md) \ No newline at end of file diff --git a/2-Intermediate/Personal-Skills/05-How to Balance Brevity and Abstraction.md b/en/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md similarity index 93% rename from 2-Intermediate/Personal-Skills/05-How to Balance Brevity and Abstraction.md rename to en/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md index c590922..0d8fd0e 100644 --- a/2-Intermediate/Personal-Skills/05-How to Balance Brevity and Abstraction.md +++ b/en/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -1,9 +1,9 @@ # How to Balance Brevity and Abstraction - -Abstraction is key to programming. You should carefully choose how abstract you need to be. Beginning programmers in their enthusiasm often create more abstraction than is really useful. One sign of this is if you create classes that don't really contain any code and don't really do anything except serve to abstract something. The attraction of this is understandable but the value of code brevity must be measured against the value of abstraction. Occasionally, one sees a mistake made by enthusiastic idealists: at the start of the project a lot of classes are defined that seem wonderfully abstract and one may speculate that they will handle every eventuality that may arise. As the project progresses and fatigue sets in, the code itself becomes messy. Function bodies become longer than they should be. The empty classes are a burden to document that is ignored when under pressure. The final result would have been better if the energy spent on abstraction had been spent on keeping things short and simple. This is a form of *speculative programming*. I strongly recommend the article 'Succinctness is Power' by Paul Graham [PGSite]. +[//]: # (Version:1.0.0) +Abstraction is key to programming. You should carefully choose how abstract you need to be. Beginning programmers in their enthusiasm often create more abstraction than is really useful. One sign of this is if you create classes that don't really contain any code and don't really do anything except serve to abstract something. The attraction of this is understandable but the value of code brevity must be measured against the value of abstraction. Occasionally, one sees a mistake made by enthusiastic idealists: at the start of the project a lot of classes are defined that seem wonderfully abstract and one may speculate that they will handle every eventuality that may arise. As the project progresses and fatigue sets in, the code itself becomes messy. Function bodies become longer than they should be. The empty classes are a burden to document that is ignored when under pressure. The final result would have been better if the energy spent on abstraction had been spent on keeping things short and simple. This is a form of *speculative programming*. I strongly recommend the article ['Succinctness is Power' by Paul Graham](http://www.paulgraham.com/power.html). There is a certain dogma associated with useful techniques such as *information hiding* and *object oriented programming* that are sometimes taken too far. These techniques let one code abstractly and anticipate change. I personally think, however, that you should not produce much speculative code. For example, it is an accepted style to hide an integer variable on an object behind mutators and accessors, so that the variable itself is not exposed, only the little interface to it. This does allow the implementation of that variable to be changed without affecting the calling code, and is perhaps appropriate to a library writer who must publish a very stable API. But I don't think the benefit of this outweighs the cost of the wordiness of it when my team owns the calling code and hence can recode the caller as easily as the called. Four or five extra lines of code is a heavy price to pay for this speculative benefit. Portability poses a similar problem. Should code be portable to a different computer, compiler, software system or platform, or simply easily ported? I think a non-portable, short-and-easily-ported piece of code is better than a long portable one. It is relatively easy and certainly a good idea to confine non-portable code to designated areas, such as a class that makes database queries that are specific to a given DBMS. -Next [How to Learn New Skills](06-How to Learn New Skills.md) \ No newline at end of file +Next [How to Learn New Skills](06-How-to-Learn-New-Skills.md) diff --git a/2-Intermediate/Personal-Skills/06-How to Learn New Skills.md b/en/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md similarity index 77% rename from 2-Intermediate/Personal-Skills/06-How to Learn New Skills.md rename to en/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md index bebcc82..5fb0846 100644 --- a/2-Intermediate/Personal-Skills/06-How to Learn New Skills.md +++ b/en/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -1,13 +1,13 @@ # How to Learn New Skills - +[//]: # (Version:1.0.0) Learning new skills, especially non-technical ones, is the greatest fun of all. Most companies would have better morale if they understood how much this motivates programmers. Humans learn by doing. Book-reading and class-taking are useful. But could you have any respect for a programmer who had never written a program? To learn any skill, you have to put yourself in a forgiving position where you can exercise that skill. When learning a new programming language, try to do a small project in it before you have to do a large project. When learning to manage a software project, try to manage a small one first. A good mentor is no replacement for doing things yourself, but is a lot better than a book. What can you offer a potential mentor in exchange for their knowledge? At a minimum, you should offer to study hard so their time won't be wasted. -Try to get your boss to let you have formal training, but understand that it often not much better than the same amount of time spent simply playing with the new skill you want to learn. It is, however, easier to ask for training than playtime in our imperfect world, even though a lot of formal training is just sleeping through lectures waiting for the dinner party. +Try to get your boss to let you have formal training, but understand that it is often not much better than the same amount of time spent simply playing with the new skill you want to learn. It is, however, easier to ask for training than playtime in our imperfect world, even though a lot of formal training is just sleeping through lectures waiting for the dinner party. If you lead people, understand how they learn and assist them by assigning them projects that are the right size and that exercise skills they are interested in. Don't forget that the most important skills for a programmer are not the technical ones. Give your people a chance to play and practice courage, honesty, and communication. -Next [Learn to Type](07-Learn to Type.md) +Next [Learn to Type](07-Learn-to-Type.md) diff --git a/2-Intermediate/Personal-Skills/07-Learn to Type.md b/en/2-Intermediate/Personal-Skills/07-Learn-to-Type.md similarity index 88% rename from 2-Intermediate/Personal-Skills/07-Learn to Type.md rename to en/2-Intermediate/Personal-Skills/07-Learn-to-Type.md index 0561fa1..0861bc4 100644 --- a/2-Intermediate/Personal-Skills/07-Learn to Type.md +++ b/en/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -1,5 +1,5 @@ # Learn to Type - +[//]: # (Version:1.0.0) Learn to touch-type. This is an intermediate skill because writing code is so hard that the speed at which you can type is irrelevant and can't put much of a dent in the time it takes to write code, no matter how good you are. However, by the time you are an intermediate programmer you will probably spend a lot of time writing natural language to your colleagues and others. This is a fun test of your commitment; it takes dedicated time that is not much fun to learn something like that. Legend has it that when Michael Tiemann was at MCC people would stand outside his door to listen to the hum generated by his keystrokes which were so rapid as to be indistinguishable. -Next [How to Do Integration Testing](08-How to Do Integration Testing.md) \ No newline at end of file +Next [How to Do Integration Testing](08-How-to-Do-Integration-Testing.md) \ No newline at end of file diff --git a/2-Intermediate/Personal-Skills/08-How to Do Integration Testing.md b/en/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md similarity index 86% rename from 2-Intermediate/Personal-Skills/08-How to Do Integration Testing.md rename to en/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md index 8b1aefe..c8f4e0a 100644 --- a/2-Intermediate/Personal-Skills/08-How to Do Integration Testing.md +++ b/en/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -1,7 +1,7 @@ # How to Do Integration Testing - +[//]: # (Version:1.0.0) Integration testing is the testing of the integration of various components that have been unit tested. Integration is expensive and it comes out in the testing. You must include time for this in your estimates and your schedule. Ideally you should organize a project so that there is not a phase at the end where integration must explicitly take place. It is far better to gradually integrate things as they are completed over the course of the project. If it is unavoidable estimate it carefully. -Next [Communication Languages](09-Communication Languages.md) \ No newline at end of file +Next [Communication Languages](09-Communication-Languages.md) \ No newline at end of file diff --git a/2-Intermediate/Personal-Skills/09-Communication Languages.md b/en/2-Intermediate/Personal-Skills/09-Communication-Languages.md similarity index 96% rename from 2-Intermediate/Personal-Skills/09-Communication Languages.md rename to en/2-Intermediate/Personal-Skills/09-Communication-Languages.md index e006c4f..5da26f9 100644 --- a/2-Intermediate/Personal-Skills/09-Communication Languages.md +++ b/en/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -1,5 +1,5 @@ # Communication Languages - +[//]: # (Version:1.0.0) There are some languages, that is, formally defined syntactic systems, that are not programming languages but *communication languages* - they are designed specifically to facilitate communication through standardization. In 2003 the most important of these are UML, XML, and SQL. You should have some familiarity with all of these so that you can communicate well and decide when to use them. UML is a rich formal system for making drawings that describe designs. Its beauty lies in that it is both visual and formal, capable of conveying a great deal of information if both the author and the audience know UML. You need to know about it because designs are sometimes communicated in it. There are very helpful tools for making UML drawings that look very professional. In a lot of cases UML is too formal, and I find myself using a simpler *boxes and arrows* style for design drawings. But I'm fairly sure UML is at least as good for you as studying Latin. @@ -8,4 +8,4 @@ XML is a standard for defining new standards. It is not a solution to data inter SQL is a very powerful and rich data query and manipulation language that is not quite a programming language. It has many variations, typically quite product-dependent, which are less important than the standardized core. SQL is the *lingua franca* of relational databases. You may or may not work in any field that can benefit from an understanding of relational databases, but you should have a basic understanding of them and the syntax and meaning of SQL. -Next [Heavy Tools](10-Heavy Tools.md) +Next [Heavy Tools](10-Heavy-Tools.md) diff --git a/2-Intermediate/Personal-Skills/10-Heavy Tools.md b/en/2-Intermediate/Personal-Skills/10-Heavy-Tools.md similarity index 88% rename from 2-Intermediate/Personal-Skills/10-Heavy Tools.md rename to en/2-Intermediate/Personal-Skills/10-Heavy-Tools.md index 1192c6e..63ca51d 100644 --- a/2-Intermediate/Personal-Skills/10-Heavy Tools.md +++ b/en/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -1,5 +1,5 @@ # Heavy Tools - + [//]: # (Version:1.0.0) As our technological culture progresses, software technology moves from inconceivable, to research, to new products, to standardized products, to widely available and inexpensive products. These heavy tools can pull great loads, but can be intimidating and require a large investment in understanding. The intermediate programmer has to know how to manage them and when they should be used or considered. To my mind right now some of the best heavy tools are: @@ -11,4 +11,4 @@ To my mind right now some of the best heavy tools are: - XML parsers, and - Spreadsheets. -Next [How to analyze data](11-How to analyze data.md) +Next [How to analyze data](11-How-to-analyze-data.md) diff --git a/2-Intermediate/Personal-Skills/11-How to analyze data.md b/en/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md similarity index 59% rename from 2-Intermediate/Personal-Skills/11-How to analyze data.md rename to en/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md index b6ede20..31a514f 100644 --- a/2-Intermediate/Personal-Skills/11-How to analyze data.md +++ b/en/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -1,11 +1,11 @@ # How to analyze data - +[//]: # (Version:1.0.0) Data analysis is a process in the early stages of software development, when you examine a business activity and find the requirements to convert it into a software application. This is a formal definition, which may lead you to believe that data analysis is an action that you should better leave to the systems analysts, while you, the programmer, should focus on coding what somebody else has designed. If we follow strictly the software engineering paradigm, it may be correct. Experienced programmers become designers and the sharpest designers become business analysts, thus being entitled to think about all the data requirements and give you a well defined task to carry out. This is not entirely accurate, because data is the core value of every programming activity. Whatever you do in your programs, you are either moving around or modifying data. The business analyst is analysing the needs in a larger scale, and the software designer is further squeezing such scale so that, when the problem lands on your desk, it seems that all you need to do is to apply clever algorithms and start moving existing data. Not so. No matter at which stage you start looking at it, data is the main concern of a well designed application. If you look closely at how a business analyst gets the requirements out of the customer's requests, you'll realize that data plays a fundamental role. The analyst creates so called Data Flow Diagrams, where all data sources are identified and the flow of information is shaped. Having clearly defined which data should be part of the system, the designer will shape up the data sources, in terms of database relations, data exchange protocols, and file formats, so that the task is ready to be passed down to the programmer. However, the process is not over yet, because you (the programmer) even after this thorough process of data refinement, are required to analyze data to perform the task in the best possible way. The bottom line of your task is the core message of Niklaus Wirth, the father of several languages. "Algorithms + Data Structures = Programs." There is never an algorithm standing alone, doing something to itself. Every algorithm is supposed to do something to at least one piece of data. -Therefore, since algorithms don't spin their wheels in a vacuum, you need to analyze both the data that somebody else has identified for you and the data that is necessary to write down your code. A trivial example will make the matter clearer. You are implementing a search routine for a library. According to your specifications, the user can select books by a combination of genre, author, title, publisher, printing year, and number of pages. The ultimate goal of your routine is to produce a legal SQL statement to search the back-end database. Based on these requirements, you have several choices: check each control in turn, using a "switch" statement, or several "if" ones; make an array of data controls, checking each element to see if it is set; create (or use) an abstract control object from which inherit all your specific controls, and connect them to an event-driven engine. If your requirements include also tuning up the query performance, by making sure that the items are checked in a specific order, you may consider using a tree of components to build your SQL statement. As you can see, the choice of the algorithm depends on the data you decide to use, or to create. Such decisions can make all the difference between an efficient algorithm and a disastrous one. However, efficiency is not the only concern. You may use a dozen named variables in your code and make it as efficient as it can ever be. But such a piece of code might not be easily maintainable. Perhaps choosing an appropriate container for your variables could keep the same speed and in addition allow your colleagues to understand the code better when they look at it next year. Furthermore, choosing a well defined data structure may allow them to extend the functionality of your code without rewriting it. In the long run, your choices of data determines how long your code will survive after you are finished with it. Let me give you another example, just some more food for thought. Let's suppose that your task is to find all the words in a dictionary with more than three anagrams, where an anagram must be another word in the same dictionary. If you think of it as a computational task, you will end up with an endless effort, trying to work out all the combinations of each word and then comparing it to the other words in the list. However, if you analyze the data at hand, you'll realize that each word may be represented by a record containing the word itself and a sorted array of its letters as ID. Armed with such knowledge, finding anagrams means just sorting the list on the additional field and picking up the ones that share the same ID. The brute force algorithm may take several days to run, while the smart one is just a matter of a few seconds. Remember this example the next time you are facing an intractable problem. +Therefore, since algorithms don't spin their wheels in a vacuum, you need to analyze both the data that somebody else has identified for you and the data that is necessary to write down your code. A trivial example will make the matter clearer. You are implementing a search routine for a library. According to your specifications, the user can select books by a combination of genre, author, title, publisher, printing year, and number of pages. The ultimate goal of your routine is to produce a legal SQL statement to search the back-end database. Based on these requirements, you have several choices: check each control in turn, using a "switch" statement, or several "if" ones; make an array of data controls, checking each element to see if it is set; create (or use) an abstract control object from which to inherit all your specific controls, and connect them to an event-driven engine. If your requirements include also tuning up the query performance, by making sure that the items are checked in a specific order, you may consider using a tree of components to build your SQL statement. As you can see, the choice of the algorithm depends on the data you decide to use, or to create. Such decisions can make all the difference between an efficient algorithm and a disastrous one. However, efficiency is not the only concern. You may use a dozen named variables in your code and make it as efficient as it can ever be. But such a piece of code might not be easily maintainable. Perhaps choosing an appropriate container for your variables could keep the same speed and in addition allow your colleagues to understand the code better when they look at it next year. Furthermore, choosing a well defined data structure may allow them to extend the functionality of your code without rewriting it. In the long run, your choices of data determines how long your code will survive after you are finished with it. Let me give you another example, just some more food for thought. Let's suppose that your task is to find all the words in a dictionary with more than three anagrams, where an anagram must be another word in the same dictionary. If you think of it as a computational task, you will end up with an endless effort, trying to work out all the combinations of each word and then comparing it to the other words in the list. However, if you analyze the data at hand, you'll realize that each word may be represented by a record containing the word itself and a sorted array of its letters as ID. Armed with such knowledge, finding anagrams means just sorting the list on the additional field and picking up the ones that share the same ID. The brute force algorithm may take several days to run, while the smart one is just a matter of a few seconds. Remember this example the next time you are facing an intractable problem. -Next [Team Skills - How to Manage Development Time](../Team-Skills/01-How to Manage Development Time.md) \ No newline at end of file +Next [Team Skills - How to Manage Development Time](../Team-Skills/01-How-to-Manage-Development-Time.md) \ No newline at end of file diff --git a/en/2-Intermediate/README.md b/en/2-Intermediate/README.md new file mode 100644 index 0000000..75294f7 --- /dev/null +++ b/en/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. Intermediate +[//]: # (Version:1.0.0) +- Personal Skills + - [How to Stay Motivated](Personal-Skills/01-How-to-Stay-Motivated.md) + - [How to be Widely Trusted](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [How to Tradeoff Time vs. Space](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [How to Stress Test](Personal-Skills/04-How-to-Stress-Test.md) + - [How to Balance Brevity and Abstraction](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [How to Learn New Skills](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Learn to Type](Personal-Skills/07-Learn-to-Type.md) + - [How to Do Integration Testing](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Communication Languages](Personal-Skills/09-Communication-Languages.md) + - [Heavy Tools](Personal-Skills/10-Heavy-Tools.md) + - [How to analyze data](Personal-Skills/11-How-to-analyze-data.md) +- Team Skills + - [How to Manage Development Time](Team-Skills/01-How-to-Manage-Development-Time.md) + - [How to Manage Third-Party Software Risks](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [How to Manage Consultants](Team-Skills/03-How-to-Manage-Consultants.md) + - [How to Communicate the Right Amount](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [How to Disagree Honestly and Get Away with It](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- Judgment + - [How to Tradeoff Quality Against Development Time](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [How to Manage Software System Dependence](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [How to Decide if Software is Too Immature](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [How to Make a Buy vs. Build Decision](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [How to Grow Professionally](Judgment/05-How-to-Grow-zProfessionally.md) + - [How to Evaluate Interviewees](Judgment/06-How-to-Evaluate-Interviewees.md) + - [How to Know When to Apply Fancy Computer Science](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [How to Talk to Non-Engineers](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/2-Intermediate/Team-Skills/01-How to Manage Development Time.md b/en/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md similarity index 90% rename from 2-Intermediate/Team-Skills/01-How to Manage Development Time.md rename to en/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md index d66cc90..ac55232 100644 --- a/2-Intermediate/Team-Skills/01-How to Manage Development Time.md +++ b/en/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -1,11 +1,11 @@ # How to Manage Development Time - +[//]: # (Version:1.0.0) To manage development time, maintain a concise and up-to-date project plan. A project plan is an estimate, a schedule, a set of milestones for marking progress, and an assignment of your team or your own time to each task on the estimate. It should also include other things you have to remember to do, such as meeting with the quality assurance people, preparing documentation, or ordering equipment. If you are on a team, the project plan should be a consensual agreement, both at the start and as you go. -The project plan exists to help make decisions, not to show how organized you are. If the project plan is either too long or not up-to-date, it will be useless for making decisions. In reality, these decisions are about individual persons. The plan and your judgement let you decide if you should shift tasks from one person to another. The milestones mark your progress. If you use a fancy project planning tool, do not be seduced into creating a Big Design Up Front (BDUF) for the project, but use it maintain concision and up-to-dateness. +The project plan exists to help make decisions, not to show how organized you are. If the project plan is either too long or not up-to-date, it will be useless for making decisions. In reality, these decisions are about individual persons. The plan and your judgement let you decide if you should shift tasks from one person to another. The milestones mark your progress. If you use a fancy project planning tool, do not be seduced into creating a Big Design Up Front (BDUF) for the project, but use it to maintain concision and up-to-dateness. If you miss a milestone, you should take immediate action such as informing your boss that the scheduled completion of that project has slipped by that amount. The estimate and schedule could never have been perfect to begin with; this creates the illusion that you might be able to make up the days you missed in the latter part of the project. You might. But it is just as likely that you have underestimated that part as that you have overestimated it. Therefore the scheduled completion of the project has already slipped, whether you like it or not. Make sure your plan includes time for: internal team meetings, demos, documentation, scheduled periodic activities, integration testing, dealing with outsiders, sickness, vacations, maintenance of existing products, and maintenance of the development environment. The project plan can serve as a way to give outsiders or your boss a view into what you or your team is doing. For this reason it should be short and up-to-date. -Next [How to Manage Third-Party Software Risks](02-How to Manage Third-Party Software Risks.md) +Next [How to Manage Third-Party Software Risks](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/2-Intermediate/Team-Skills/02-How to Manage Third-Party Software Risks.md b/en/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md similarity index 95% rename from 2-Intermediate/Team-Skills/02-How to Manage Third-Party Software Risks.md rename to en/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md index eb3f44d..378b0fd 100644 --- a/2-Intermediate/Team-Skills/02-How to Manage Third-Party Software Risks.md +++ b/en/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -1,5 +1,5 @@ # How to Manage Third-Party Software Risks - +[//]: # (Version:1.0.0) A project often depends on software produced by organizations that it does not control. There are great risks associated with third party software that must be recognized by everyone involved. Never, ever, rest any hopes on *vapour*. Vapour is any alleged software that has been promised but is not yet available. This is the surest way to go out of business. It is unwise to be merely sceptical of a software company's promise to release a certain product with a certain feature at a certain date; it is far wiser to ignore it completely and forget you ever heard it. Never let it be written down in any documents used by your company. @@ -8,4 +8,4 @@ If third-party software is not vapour, it is still risky, but at least it is a r Understanding the suitability of existing third party software for a particular purpose is very tribal knowledge. It is very subjective and generally resides in experts. You can save a lot of time if you can find those experts. Often times a project will depend on a third-party software system so completely that if the integration fails the project will fail. Express risks like that clearly in writing in the schedule. Try to have a contingency plan, such as another system that can be used or the ability to write the functionality yourself if the risk can't be removed early. Never let a schedule depend on vapour. -Next [How to Manage Consultants](03-How to Manage Consultants.md) \ No newline at end of file +Next [How to Manage Consultants](03-How-to-Manage-Consultants.md) \ No newline at end of file diff --git a/en/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/en/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..9e963f7 --- /dev/null +++ b/en/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,23 @@ +# How to Manage Consultants + +If you get appointed as technical leader of some project in a medium/big company, most likely you’ll have to deal with consultants. This is a really delicate matter, because your company is going to pay for those additional resources but the results will mostly depend on how you manage them. +“Your professional reputation depends on consultants’ performance more than consultants’ careers depend on your feedback.” +Use consultants, but don't rely on them. They are wonderful people and deserve a great deal of respect. Since they get to see a lot of different projects, they often know more about specific technologies and even programming techniques than you will. The best way to use them is as educators in-house that can teach by example. After all, they are here to do something that regular employees cannot do, either because there is a big workload or because employees actually don't know how to do it. +However, they usually cannot become part of the team in the same sense that regular employees are, if only because you may not have enough time to learn their strengths and weaknesses. Their financial commitment is much lower. They can move more easily. They may have less to gain if the company does well. +Formally you are the “customer”, so you have the right to expect what you payed for – results – but this cannot be achieved just by scheduling deadlines. To get the most from consultants, you’ll have to leverage on your social skills more than rely on project management or scrum tools: +- start building a seamless team; ask consultants to join for coffee break or lunch with you and the other regular employee team members. +- show consideration; start from remember consultants’ names correctly. It’s always unpleasant when someone doesn’t remember your name or spells it wrong, but if this is perceived not as simple mistake but driven by poor consideration by the customer personnel towards the consultant it becomes very annoying. +- create empathy; include consultants when you say "we" while talking about the project your team is working on, let them feel that they will be really part of the success you want to achieve. + +Remember that an annoyed consultant will perform very poorly, resulting in an economic damage for your company and a misstep for you as a leader. +If consultants are going to write code, you must review it carefully as you go along. You cannot get to the end of the project with the risk of a large block of code that has not been reviewed. This is true of all team members, really, but you will usually have more knowledge of the team members closer to you. + +You should always take into account that writing readable and maintainable code is not the main priority of a consultant - its goal is to meet client expectation which are mostly expressed in terms of deadlines and functionalities that shall be implemented. +When deadlines are approaching, consultant are masters in rapidly patching software to make it work quickly – even if that means to embed into source code something like configuration parameters or fake data. + +This is why you should explicitly ask consultant to write good code, more than reviewing every single LOC – establish the expectation that the extra effort spent for writing elegant and reusable code will be appreciated. + +Another good practice is to make every team member accountable in the same way for the work they produce – e.g. make mandatory for everyone to provide header comment blocks into programming code or editor/reviewers tables into delivered documents so that any file can be attributed to its author. Given the current emphasis about online professional reputation and personal branding, accountability will be a lever for consultants to avoid delivering something that they wouldn’t be proud of, encouraged by the fact that they could be already gone somewhere else when poor quality of their job is revealed. + + +Next [How to Communicate the Right Amount](04-How to Communicate the Right Amount.md) diff --git a/2-Intermediate/Team-Skills/04-How to Communicate the Right Amount.md b/en/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md similarity index 82% rename from 2-Intermediate/Team-Skills/04-How to Communicate the Right Amount.md rename to en/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md index 55bd84e..f09c809 100644 --- a/2-Intermediate/Team-Skills/04-How to Communicate the Right Amount.md +++ b/en/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -1,7 +1,7 @@ # How to Communicate the Right Amount - +[//]: # (Version:1.0.0) Carefully consider the cost of a meeting; it costs *its duration multiplied by the number of participants*. Meetings are sometimes necessary, but smaller is usually better. The quality of communication in small meetings is better, and less time overall is wasted. If any one person is bored at a meeting take this as a sign that the meeting should be smaller. Everything possible should be done to encourage informal communication. More useful work is done during lunches with colleagues than during any other time. It is a shame that more companies do not recognize nor support this fact. -Next [How to Disagree Honestly and Get Away with It](05-How to Disagree Honestly and Get Away with It.md) +Next [How to Disagree Honestly and Get Away with It](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/2-Intermediate/Team-Skills/05-How to Disagree Honestly and Get Away with It.md b/en/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md similarity index 95% rename from 2-Intermediate/Team-Skills/05-How to Disagree Honestly and Get Away with It.md rename to en/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md index 022ab50..f639011 100644 --- a/2-Intermediate/Team-Skills/05-How to Disagree Honestly and Get Away with It.md +++ b/en/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -1,5 +1,5 @@ # How to Disagree Honestly and Get Away with It - +[//]: # (Version:1.0.0) Disagreement is a great opportunity to make a good decision, but it should be handled delicately. Hopefully you feel that you have expressed your thoughts adequately and been heard before the decision is made. In that case there is nothing more to say, and you should decide whether you will stand behind the decision even though you disagree with it. If you can support this decision even though you disagree, say so. This shows how valuable you are because you are independent and are not a yes-man, but respectful of the decision and a team player. Sometimes a decision that you disagree with will be made when the decision makers did not have the full benefit of your opinion. You should then evaluate whether to raise the issue on the basis of the benefit to the company or tribe. If it is a small mistake in your opinion, it may not be worth reconsidering. If it is a large mistake in your opinion, then of course you must present an argument. @@ -8,4 +8,4 @@ Usually, this is not a problem. In some stressful circumstances and with some pe Whether the decision is reversed or not, you must remember that you will never be able to say ‘I told you so!’ since the alternate decision was fully explored. -Next [Judgment - How to Tradeoff Quality Against Development Time](../Judgment/01-How to Tradeoff Quality Against Development Time.md) +Next [Judgment - How to Tradeoff Quality Against Development Time](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/3-Advanced/Compromising-Wisely/01-How to Fight Schedule Pressure.md b/en/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md similarity index 96% rename from 3-Advanced/Compromising-Wisely/01-How to Fight Schedule Pressure.md rename to en/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md index 4cbbf85..5cc8b7a 100644 --- a/3-Advanced/Compromising-Wisely/01-How to Fight Schedule Pressure.md +++ b/en/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -1,5 +1,5 @@ # How to Fight Schedule Pressure - +[//]: # (Version:1.0.0) Time-to-market pressure is the pressure to deliver a good product quickly. It is good because it reflects a financial reality, and is healthy up to a point. Schedule pressure is the pressure to deliver something faster than it can be delivered and it is wasteful, unhealthy, and all too common. Schedule pressure exists for several reasons. The people who task programmers do not fully appreciate what a strong work ethic we have and how much fun it is to be a programmer. Perhaps because they project their own behaviour onto us, they believe that asking for it sooner will make us work harder to get it there sooner. This is probably actually true, but the effect is very small, and the damage is very great. Additionally, they have no visibility into what it really takes to produce software. Not being able to see it, and not be able to create it themselves, the only thing they can do is see time-to-market pressure and fuss at programmers about it. @@ -8,4 +8,4 @@ The key to fighting schedule pressure is simply to turn it into time-to-market p The key insight that the estimate must make plain is that labour is an almost incompressible fluid. You can't pack more into a span of time anymore than you can pack more water into a container over and above that container's volume. In a sense, a programmer should never say ‘no’, but rather to say ‘What will you give up to get that thing you want?’ The effect of producing clear estimates will be to increase the respect for programmers. This is how other professionals behave. Programmers' hard work will be visible. Setting an unrealistic schedule will also be painfully obvious to everyone. Programmers cannot be hoodwinked. It is disrespectful and demoralizing to ask them to do something unrealistic. Extreme Programming amplifies this and builds a process around it; I hope that every reader will be lucky enough to use it. -Next [How to Understand the User](02-How to Understand the User.md) \ No newline at end of file +Next [How to Understand the User](02-How-to-Understand-the-User.md) \ No newline at end of file diff --git a/3-Advanced/Compromising-Wisely/02-How to Understand the User.md b/en/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md similarity index 95% rename from 3-Advanced/Compromising-Wisely/02-How to Understand the User.md rename to en/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md index 1e3d1c0..62e4950 100644 --- a/3-Advanced/Compromising-Wisely/02-How to Understand the User.md +++ b/en/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -1,5 +1,5 @@ # How to Understand the User - +[//]: # (Version:1.0.0) It is your duty to understand the user, and to help your boss understand the user. Because the user is not as intimately involved in the creation of your product as you are, they behave a little differently: - The user generally makes short pronouncements. @@ -14,4 +14,4 @@ Guy Kawasaki [Rules] has emphasized the importance of *watching* what your users I believe contractors and consultants often have tremendous problems getting their clients to clarify in their own minds what they really want. If you intend to be a consultant, I suggest you choose your clients based on their clear-headedness as well as their pocketbooks. -Next [How to Get a Promotion](03-How to Get a Promotion.md) \ No newline at end of file +Next [How to Get a Promotion](03-How-to-Get-a-Promotion.md) \ No newline at end of file diff --git a/3-Advanced/Compromising-Wisely/03-How to Get a Promotion.md b/en/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md similarity index 95% rename from 3-Advanced/Compromising-Wisely/03-How to Get a Promotion.md rename to en/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md index 1ea1510..b0cfbf6 100644 --- a/3-Advanced/Compromising-Wisely/03-How to Get a Promotion.md +++ b/en/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -1,5 +1,5 @@ # How to Get a Promotion - +[//]: # (Version:1.0.0) To be promoted to a role, act out that role first. To get promoted to a title, find out what is expected of that title and do that. @@ -10,4 +10,4 @@ If you feel like you are past due for a promotion, talk to your boss about it. A Most programmers probably have an exaggerated sense of their relative abilities in some ways---after all, we can't all be in the top 10%! However, I have seen some people who were seriously unappreciated. One cannot expect everyone's evaluation to perfectly match reality at all times, but I think people are generally moderately fair, with one caveat: you cannot be appreciated without visibility into your work. Sometimes, due to happenstance or personal habits, someone will not be noticed much. Working from home a lot or being geographically separated from your team and boss makes this especially difficult. -Next [Serving Your Team - How to Develop Talent](../Serving-Your-Team/01-How to Develop Talent.md) +Next [Serving Your Team - How to Develop Talent](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/en/3-Advanced/README.md b/en/3-Advanced/README.md new file mode 100644 index 0000000..85d0b2e --- /dev/null +++ b/en/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. Advanced +[//]: # (Version:1.0.0) +- Technological Judgment + - [How to Tell the Hard From the Impossible](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [How to Utilize Embedded Languages](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Choosing Languages](Technical-Judgment/03-Choosing-Languages.md) +- Compromising Wisely + - [How to Fight Schedule Pressure](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [How to Understand the User](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [How to Get a Promotion](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- Serving Your Team + - [How to Develop Talent](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [How to Choose What to Work On](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [How to Get the Most From Your Team-mates](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [How to Divide Problems Up](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [How to Handle Boring Tasks](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [How to Gather Support for a Project](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [How to Grow a System](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [How to Communicate Well](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [How to Tell People Things They Don't Want to Hear](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [How to Deal with Managerial Myths](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [How to Deal with Organizational Chaos](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/3-Advanced/Serving-Your-Team/01-How to Develop Talent.md b/en/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md similarity index 97% rename from 3-Advanced/Serving-Your-Team/01-How to Develop Talent.md rename to en/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md index e853798..c95aa23 100644 --- a/3-Advanced/Serving-Your-Team/01-How to Develop Talent.md +++ b/en/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -20,4 +20,4 @@ It is an odd fact that is not reflected in salaries that a good programmer is mo You can often give the stronger team members challenging, but carefully delineated, tasks. -Next [How to Choose What to Work On](02-How to Choose What to Work On.md) \ No newline at end of file +Next [How to Choose What to Work On](02-How-to-Choose-What-to-Work-On.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/02-How to Choose What to Work On.md b/en/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md similarity index 83% rename from 3-Advanced/Serving-Your-Team/02-How to Choose What to Work On.md rename to en/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md index c13705c..2b5cd41 100644 --- a/3-Advanced/Serving-Your-Team/02-How to Choose What to Work On.md +++ b/en/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -2,4 +2,4 @@ You balance your personal needs against the needs of the team in choosing what aspect of a project to work on. You should do what you are best at, but try to find a way to stretch yourself not by taking on more work but by exercising a new skill. Leadership and communication skills are more important than technical skills. If you are very strong, take on the hardest or riskiest task, and do it as early as possible in the project to decrease risk. -Next [How to Get the Most From Your Team-mates](03-How to Get the Most From Your Teammates.md) \ No newline at end of file +Next [How to Get the Most From Your Team-mates](03-How-to-Get-the-Most-From-Your-Teammates.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/03-How to Get the Most From Your Teammates.md b/en/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md similarity index 97% rename from 3-Advanced/Serving-Your-Team/03-How to Get the Most From Your Teammates.md rename to en/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md index 1b046db..1f7edaa 100644 --- a/3-Advanced/Serving-Your-Team/03-How to Get the Most From Your Teammates.md +++ b/en/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -12,4 +12,4 @@ Ask your team, both as a group and individually, what they think would create te Praise frequently rather than lavishly. Especially praise those who disagree with you when they are praiseworthy. Praise in public and criticize in private; with one exception: sometimes growth or the correction of a fault can't be praised without drawing embarrassing attention to the original fault, so that growth should be praised in private. -Next [How to Divide Problems Up](04-How to Divide Problems Up.md) \ No newline at end of file +Next [How to Divide Problems Up](04-How-to-Divide-Problems-Up.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/04-How to Divide Problems Up.md b/en/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md similarity index 94% rename from 3-Advanced/Serving-Your-Team/04-How to Divide Problems Up.md rename to en/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md index 4ee4d14..b8d3ef5 100644 --- a/3-Advanced/Serving-Your-Team/04-How to Divide Problems Up.md +++ b/en/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -6,4 +6,4 @@ Just as a composer considers the timbre of the instrument that will play a part There is a certain danger in this given that people will become bored as they build upon their strengths and never improve their weaknesses or learn new skills. However, specialization is a very useful productivity tool when not overused. -Next [How to Handle Boring Tasks](05-How to Handle Boring Tasks.md) \ No newline at end of file +Next [How to Handle Boring Tasks](05-How-to-Handle-Boring-Tasks.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/05-How to Handle Boring Tasks.md b/en/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md similarity index 90% rename from 3-Advanced/Serving-Your-Team/05-How to Handle Boring Tasks.md rename to en/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md index dfdb8b9..a302dd5 100644 --- a/3-Advanced/Serving-Your-Team/05-How to Handle Boring Tasks.md +++ b/en/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -4,4 +4,4 @@ Sometimes it is not possible to avoid boring tasks that are critical to the succ If all else fails, apologize to those who have to do the boring task, but under no circumstances allow them to do it alone. At a minimum assign a team of two to do the work and promote healthy teamwork to get the task done. -Next [How to Gather Support for a Project](06-How to Gather Support for a Project.md) \ No newline at end of file +Next [How to Gather Support for a Project](06-How-to-Gather-Support-for-a-Project.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/06-How to Gather Support for a Project.md b/en/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md similarity index 91% rename from 3-Advanced/Serving-Your-Team/06-How to Gather Support for a Project.md rename to en/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md index 3ba9eaf..b5710ca 100644 --- a/3-Advanced/Serving-Your-Team/06-How to Gather Support for a Project.md +++ b/en/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -2,4 +2,4 @@ To gather support for a project, create and communicate a vision that demonstrates real value to the organization as a whole. Attempt to let others share in your vision creation. This gives them a reason to support you and gives you the benefit of their ideas. Individually recruit key supporters for your project. Wherever possible, show, don't tell. If possible, construct a prototype or a mock-up to demonstrate your ideas. A prototype is always powerful but in software it is far superior to any written description. -Next [How to Grow a System](07-How to Grow a System.md) \ No newline at end of file +Next [How to Grow a System](07-How-to-Grow-a-System.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/07-How to Grow a System.md b/en/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md similarity index 97% rename from 3-Advanced/Serving-Your-Team/07-How to Grow a System.md rename to en/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md index 5aa9f8c..0f71189 100644 --- a/3-Advanced/Serving-Your-Team/07-How to Grow a System.md +++ b/en/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -20,4 +20,4 @@ A reader, Rob Hafernik, sent in this comment on this section that I can do no be To which one can only reply *Fiat lux*! -Next [How to Communiate Well](08-How to Communicate Well.md) \ No newline at end of file +Next [How to Communicate Well](08-How-to-Communicate-Well.md) diff --git a/3-Advanced/Serving-Your-Team/08-How to Communicate Well.md b/en/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md similarity index 71% rename from 3-Advanced/Serving-Your-Team/08-How to Communicate Well.md rename to en/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md index 4e55ee2..29e5fa9 100644 --- a/3-Advanced/Serving-Your-Team/08-How to Communicate Well.md +++ b/en/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -6,6 +6,6 @@ The programmer is a social animal whose survival depends on communication with h The programmer brings order out of chaos. One interesting way to do this is to initiate a proposal of some kind outside the team. This can be done in a *strawman* or *white-paper* format or just verbally. This leadership has the tremendous advantage of setting the terms of the debate. It also exposes you to criticism, and worse, rejection and neglect. The advanced programmer must be prepared to accept this, because she has a unique power and therefore a unique responsibility. Entrepreneurs who are not programmers need programmers to provide leadership in some ways. Programmers are the part of the bridge between ideas and reality that rests on reality. -I haven't mastered communicating well, but what I'm currently trying is what I think of a four-pronged approach: After I have my ideas in order and am fully prepared, I try to speak verbally, hand people a white-paper (on real paper, as well as electronically) show them a demo, and then patiently repeat this process. I think a lot of times we are not patient enough in this kind of difficult communication. You should not be disheartened if your ideas are not immediately accepted. If you have invested energy in their preparation, no one will think poorly of you for it. +I haven't mastered communicating well, but what I'm currently trying is what I think of as a four-pronged approach: After I have my ideas in order and am fully prepared, I try to speak verbally, hand people a white-paper (on real paper, as well as electronically) show them a demo, and then patiently repeat this process. I think a lot of times we are not patient enough in this kind of difficult communication. You should not be disheartened if your ideas are not immediately accepted. If you have invested energy in their preparation, no one will think poorly of you for it. -Next [How to Tell People Things They Don't Want to Hear](09-How to Tell People Things They Don't Want to Hear.md) +Next [How to Tell People Things They Don't Want to Hear](09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) diff --git a/3-Advanced/Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md b/en/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md similarity index 93% rename from 3-Advanced/Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md rename to en/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md index dc6c539..3d294df 100644 --- a/3-Advanced/Serving-Your-Team/09-How to Tell People Things They Don't Want to Hear.md +++ b/en/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -6,4 +6,4 @@ The best way to tell someone about a problem is to offer a solution at the same One of the most unpleasant and common things you will have to say is, ‘The schedule will have to slip.’ The conscientious programmer hates to say this, but must say it as early as possible. There is nothing worse than postponing action when a milestone slips, even if the only action is to inform everyone. In doing this, it is better to do it as a team, at least in spirit, if not physically. You will want your team's input on both where you stand and what can be done about it, and the team will have to face the consequences with you. -Next [How to Deal with Managerial Myths](10-How to Deal with Managerial Myths.md) +Next [How to Deal with Managerial Myths](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/3-Advanced/Serving-Your-Team/10-How to Deal with Managerial Myths.md b/en/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md similarity index 94% rename from 3-Advanced/Serving-Your-Team/10-How to Deal with Managerial Myths.md rename to en/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md index 6acb49d..8288078 100644 --- a/3-Advanced/Serving-Your-Team/10-How to Deal with Managerial Myths.md +++ b/en/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -10,4 +10,4 @@ The word *myth* sometimes means fiction. But it has a deeper connotation. It als If you have an opportunity, you can try to explain these things, but don't feel bad if you have no success and don't damage your reputation by confronting these myths belligerently. Each of these myths reinforces the manager's idea that they have some actual control over what is going on. The truth is that managers facilitate if they are good, and impede if they are bad. -Next [How to Deal with Organizational Chaos](11-How to Deal with Organizational Chaos.md) \ No newline at end of file +Next [How to Deal with Organizational Chaos](11-How-to-Deal-with-Organizational-Chaos.md) \ No newline at end of file diff --git a/3-Advanced/Serving-Your-Team/11-How to Deal with Organizational Chaos.md b/en/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md similarity index 100% rename from 3-Advanced/Serving-Your-Team/11-How to Deal with Organizational Chaos.md rename to en/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md diff --git a/en/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/en/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..9429114 --- /dev/null +++ b/en/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# How to Tell the Hard From the Impossible +[//]: # (Version:1.0.1) +It is our job to do the hard and discern the impossible. From the point of view of most working programmers, something is impossible if either it cannot be grown from a simple system or it cannot be estimated. By this definition, what is called research is impossible. A large volume of mere work is hard, but not necessarily impossible. + +The distinction is not facetious, because you may very well be asked to do what is practically impossible, either from a scientific point of view or a software engineering one. It then becomes your job to help the entrepreneur find a reasonable solution, which is merely hard, and gets most of what they wanted. A solution is merely hard when it can be confidently scheduled and the risks are understood. + +It is impossible to satisfy a vague requirement, such as ‘Build a system that will compute the most attractive hair style and colour for any person.’ If the requirement can be made more crisp, it will often become merely hard, such as ‘Build a system to compute an attractive hair style and colour for a person, allow them to preview it and make changes, and have the customer satisfaction based on the original styling be so great that we make a lot of money.’ If there is no crisp definition of success, you will not succeed. + +Next [How to Utilize Embedded Languages](02-How-to-Utilize-Embedded-Languages.md) diff --git a/3-Advanced/Technical-Judgment/02-How to Utilize Embedded Languages.md b/en/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md similarity index 96% rename from 3-Advanced/Technical-Judgment/02-How to Utilize Embedded Languages.md rename to en/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md index dc1d8ac..3900d86 100644 --- a/3-Advanced/Technical-Judgment/02-How to Utilize Embedded Languages.md +++ b/en/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -8,4 +8,4 @@ I and many other programmers have fallen into the trap of creating special purpo The real question to ask oneself before embedding a language is: Does this work with or against the culture of my audience? If you intended audience is exclusively non-programmers, how will it help? If your intended audience is exclusively programmers, would they prefer an applications programmers interface (API)? And what language will it be? Programmers don't want to learn a new language that is narrowly used; but if it meshes with their culture they will not have to spend much time learning it. It is a joy to create a new language. But we should not let that blind us to the needs of the user. Unless you have some truly original needs and ideas, why not use an existing language so that you can leverage the familiarity users already have with it? -Next [Choosing Languages](03-Choosing Languages.md) \ No newline at end of file +Next [Choosing Languages](03-Choosing-Languages.md) diff --git a/3-Advanced/Technical-Judgment/03-Choosing Languages.md b/en/3-Advanced/Technical-Judgment/03-Choosing-Languages.md similarity index 89% rename from 3-Advanced/Technical-Judgment/03-Choosing Languages.md rename to en/3-Advanced/Technical-Judgment/03-Choosing-Languages.md index 22b3a22..73ec051 100644 --- a/3-Advanced/Technical-Judgment/03-Choosing Languages.md +++ b/en/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -1,6 +1,6 @@ # Choosing Languages -The solitary programmer that loves his work (a hacker) can choose the best language for the task. Most working programmers have very little control of the language they will use. Generally, this issue is dictated by pointy-haired bosses who are making a political decision, rather than a technological decision, and lack the courage to promote an unconventional tool even when they know, often with first-hand knowledge, that the less accepted tool is best. In other cases the very real benefit of unity among the team, and to some extent with a larger community, precludes choice on the part of the individual. Often managers are driven by the need to be able to hire programmers with experience in a given language. No doubt they are serving what they perceive to be the best interests of the project or company, and must be respected for that. However, I personally believe this the most wasteful and erroneous common practice you are likely to encounter. +The solitary programmer that loves his work (a hacker) can choose the best language for the task. Most working programmers have very little control of the language they will use. Generally, this issue is dictated by pointy-haired bosses who are making a political decision, rather than a technological decision, and lack the courage to promote an unconventional tool even when they know, often with first-hand knowledge, that the less accepted tool is best. In other cases the very real benefit of unity among the team, and to some extent with a larger community, precludes choice on the part of the individual. Often managers are driven by the need to be able to hire programmers with experience in a given language. No doubt they are serving what they perceive to be the best interests of the project or company, and must be respected for that. However, I personally believe this is the most wasteful and erroneous common practice you are likely to encounter. But of course, things are never one-dimensional. Even if a core language is mandated and beyond your control, it is often the case that tools and other programs can and should be written in a different language. If a language is to be embedded (and you should always consider it!) the choice of language will depend a lot on the culture of the users. One should take advantage of this to serve your company or project by using the best language for the job, and in so doing make work more interesting. @@ -10,6 +10,6 @@ Programming languages should really be called notations in that learning one is - You can evolve to a new language/platform easily by rewriting each component individually, - One language may not be a good fit for the overall system - having multiple languages for your modules allows you to pick the right tool for the job. -Some of these effects may only be psychological; but psychology matters. In the end the costs of language tyranny outweigh any advantage that it provides. +Some of these effects may only be psychological; but psychology matters. In the end, the costs of language tyranny outweigh any advantage that it provides. -Next [Compromising Wisely - How to Fight a Schedule Pressure](../Compromising-Wisely/01-How to Fight Schedule Pressure.md) +Next [Compromising Wisely - How to Fight a Schedule Pressure](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/5-Bibliography.md b/en/5-Bibliography.md similarity index 98% rename from 5-Bibliography.md rename to en/5-Bibliography.md index aa741ea..e96590e 100644 --- a/5-Bibliography.md +++ b/en/5-Bibliography.md @@ -1,5 +1,5 @@ # Appendix A - Bibliography/Websiteography - +[//]: # (Version:1.0.0) ## Books [Rules00] Guy Kawasaki, Michelle Moreno, and Gary Kawasaki. 2000. HarperBusiness. Rules for Revolutionaries: The Capitalist Manifesto for Creating and Marketing New Products and Services. diff --git a/6-History.md b/en/6-History.md similarity index 99% rename from 6-History.md rename to en/6-History.md index 0e09a87..4a46e40 100644 --- a/6-History.md +++ b/en/6-History.md @@ -1,5 +1,5 @@ # Appendix B - History - +[//]: # (Version:1.0.0) ## Move to Github This essay has been created as a repository on Github so that it can be easily shared, updated and improved. It was copied from [http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm) by [Braydie Grove](https://github.com/braydie). It was moved to Github in January 2016. diff --git a/7-Contributions.md b/en/7-Contributions.md similarity index 59% rename from 7-Contributions.md rename to en/7-Contributions.md index 52892e9..f6e163c 100644 --- a/7-Contributions.md +++ b/en/7-Contributions.md @@ -1,5 +1,5 @@ # Contributions - +[//]: # (Version:1.0.0) This repository aims to be a community driven project, and your involvement will ultimately help improve the quality of this guide. ## What can I do to contribute? @@ -10,6 +10,17 @@ There are a number of ways to contribute to "How to be a Programmer". - Identifying typos or other issues in sections - Contributing additional links to resources for sections - General suggestions for improving the project +- Provide translations of the guide + +## Translations + +Currently this guide has been translated from English into the following languages: + +- Chinese by [ahangchen](https://github.com/ahangchen) +- Russian by [paveltovchigrechko](https://github.com/paveltovchigrechko) +- Spanish by [Maximiliano Murua](https://gitlab.com/maximiliano.murua) + +**If you provide the initial translation of the guide into another language, you become legible to become a contributor on this project to help maintain and review changes made to the translation.** ## Contributors diff --git a/en/GLOSSARY.md b/en/GLOSSARY.md new file mode 100644 index 0000000..9e50838 --- /dev/null +++ b/en/GLOSSARY.md @@ -0,0 +1,131 @@ +# Glossary +[//]: # (Version:1.0.0) +This is a glossary of terms as used in this essay. These do not necessarily have a standardized meaning to other people. Eric S. Raymond has compiled a massive and informative glossary[HackerDict] that rather surprisingly can pleasurably be read cover-to-cover once you can appreciate a fraction of it. + +### unk-unk + +Slang for unknown-unknown. Problems that cannot presently even be conceptualized that will steal time away from the project and wreck the schedule. + +### printlining + +The insertion of statements into a program on a strictly temporary basis that output information about the execution of the program for the purpose of debugging. + +### logging + +The practice of writing a program so that it can produce a configurable output log describing its execution. + +### divide and conquer + +A technique of top-down design and, importantly, of debugging that is the subdivision of a problem or a mystery into progressively smaller problems or mysteries. + +### vapour + +Illusionary and often deceptive promises of software that is not yet for sale and, as often as not, will never materialize into anything solid. + +### boss + +The person who sets your tasks. In some cases, the user is the boss. + +### tribe + +The people with whom you share loyalty to a common goal. + +### low-hanging fruit + +Big improvements that cost little. + +### Entrepreneur + +The initiator of projects. + +### business + +A group of people organized for making money. + +### company + +A group of people organized for making money. + +### scroll blindness + +The effect of being unable to find information you need because it is buried in too much other, less interesting information. + +### wall-clock + +Actually time as measured by a clock on a wall, as opposed to CPU time. + +### bottleneck + +The most important limitation in the performance of a system. A constriction that limits performance. + +### master + +A unique piece of information from which all cached copies are derived that serves as the official definition of that data. + +### heap allocated + +Memory can be said to be heap allocated whenever the mechanism for freeing it is complicated. + +### garbage + +Memory which is being taken up by objects your application no longer needs. + +### garbage collector + +A system for recycling garbage. + +### memory leak + +The unwanted collection of references to objects that prevents garbage collection (or a bug in the garbage collector or memory management system!) that causes the program to gradually increase its memory demands over time. + +### Extreme Programming + +A style of programming emphasizing communication with the customer and automated testing. + +### hitting the wall + +To run out of a specific resource causing performance to degrade sharply rather than gradually. + +### speculative programming + +Producing a feature before it is really known if that feature will be useful. + +### information hiding + +A design principle that seeks to keep things independent and decoupled by using interfaces that expose as little information as possible. + +### object-oriented programming + +An programming style emphasizing the the management of state inside objects. + +### communication languages + +A language designed primarily for standardization rather than execution. + +### boxes and arrows + +A loose, informal style of making diagrams consisting of boxes and arrows drawn between those boxes to show the relationships. This contrast with formal diagram methodologies, such as UML. + +### lingua franca + +A language so popular as to be a de facto standard for its field, as French was for international diplomacy at one time. + +### buy vs. build + +An adjective describing a choice between spending money for software or writing it your self. + +### mere work + +Work that requires little creativity and entails little risk. Mere work can be estimated easily. + +### programming notation + +A synonym for programming language that emphasizes the mathematical nature of programming language and their relative simplicity compared to natural languages. + +### strawman + +A document meant to be the starting point of a technical discussion. A strawman may lead to a stickman, tinman, woodman, ironman, etc. + +### white-paper + +An informative document that is often meant to explain or sell a product or idea to an audience different than the programmers of that product or idea. diff --git a/LICENSE.md b/en/LICENSE.md similarity index 100% rename from LICENSE.md rename to en/LICENSE.md diff --git a/en/README.md b/en/README.md new file mode 100644 index 0000000..c0f0f22 --- /dev/null +++ b/en/README.md @@ -0,0 +1,103 @@ +# How to be a Programmer: Community Version +[//]: # (Version:1.0.0) +Robert L. Read with Community + +Copyright 2002, 2003, 2016 Robert L. Read + +Licensed under [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +## Introduction +To be a good programmer is difficult and noble. The hardest part of making real a collective vision of a software project is dealing with one's coworkers and customers. Writing computer programs is important and takes great intelligence and skill. But it is really child's play compared to everything else that a good programmer must do to make a software system that succeeds for both the customer and myriad colleagues for whom she is partially responsible. In this essay I attempt to summarize as concisely as possible those things that I wish someone had explained to me when I was twenty-one. + +This is very subjective and, therefore, this essay is doomed to be personal and somewhat opinionated. I confine myself to problems that a programmer is very likely to have to face in her work. Many of these problems and their solutions are so general to the human condition that I will probably seem preachy. I hope in spite of this that this essay will be useful. + +Computer programming is taught in courses. The excellent books: The Pragmatic Programmer [Prag99], Code Complete [CodeC93], Rapid Development [RDev96], and Extreme Programming Explained [XP99] all teach computer programming and the larger issues of being a good programmer. The essays of Paul Graham [PGSite] and Eric Raymond [Hacker] should certainly be read before or along with this article. This essay differs from those excellent works by emphasizing social problems and comprehensively summarizing the entire set of necessary skills as I see them. + +In this essay the term boss is used to refer to whomever gives you projects to do. I use the words business, company, and tribe, synonymously except that business connotes moneymaking, company connotes the modern workplace and tribe is generally the people you share loyalty with. + +Welcome to the tribe. + +## Contents + +1. [Beginner](1-Beginner) + - Personal Skills + - [Learn to Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [How to Remove an Error](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [How to Optimize Loops](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [How to Manage Memory](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - Team Skills + - [Why Estimation is Important](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [How to Find Out Information](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [How to Document Wisely](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [How to Work with Poor Code](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [How to Use Source Code Control](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [How to Unit Test](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [Intermediate](2-Intermediate) + - Personal Skills + - [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [How to Stress Test](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Learn to Type](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Communication Languages](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [How to analyze data](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - Team Skills + - [How to Manage Development Time](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [How to Manage Consultants](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - Judgment + - [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [How to Grow Professionally](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [Advanced](3-Advanced) + - Technological Judgment + - [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - Compromising Wisely + - [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [How to Understand the User](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - Serving Your Team + - [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [How to Grow a System](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [Glossary](GLOSSARY.md) +5. [Appendix A - Bibliography/Websiteography](5-Bibliography.md) +6. [Appendix B - History (As of January 2016)](6-History.md) +6. [Appendix C - Contributions (As of January 2016)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/en/SUMMARY.md b/en/SUMMARY.md new file mode 100644 index 0000000..e442482 --- /dev/null +++ b/en/SUMMARY.md @@ -0,0 +1,80 @@ +# Summary +[//]: # (Version:1.0.0) +* [Beginner](1-Beginner/README.md) + * Personal Skills + * [Learn to Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + * [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + * [How to Remove an Error](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + * [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + * [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + * [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + * [How to Optimize Loops](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + * [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + * [How to Manage Memory](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + * [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + * [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + * [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + * Team Skills + * [Why Estimation is Important](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + * [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + * [How to Find Out Information](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + * [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + * [How to Document Wisely](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + * [How to Work with Poor Code](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + * [How to Use Source Code Control](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + * [How to Unit Test](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + * [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + * [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + * [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +* [Intermediate](2-Intermediate/README.md) + * Personal Skills + * [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + * [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + * [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + * [How to Stress Test](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + * [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + * [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + * [Learn to Type](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + * [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + * [Communication Languages](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + * [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + * [How to analyze data](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + * Team Skills + * [How to Manage Development Time](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + * [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + * [How to Manage Consultants](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + * [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + * [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + * Judgment + * [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + * [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + * [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + * [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + * [How to Grow Professionally](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + * [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + * [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + * [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +* [Advanced](3-Advanced/README.md) + * Technological Judgment + * [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + * [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + * [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + * Compromising Wisely + * [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + * [How to Understand the User](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + * [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + * Serving Your Team + * [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + * [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + * [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + * [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + * [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + * [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + * [How to Grow a System](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + * [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + * [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + * [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + * [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +* [Appendix A * Bibliography/Websiteography](5-Bibliography.md) +* [Appendix B * History (As of January 2016)](6-History.md) +* [Appendix C * Contributions (As of January 2016)](7-Contributions.md) diff --git a/es/1-Beginner/Personal-Skills/01-Learn-To-Debug.md b/es/1-Beginner/Personal-Skills/01-Learn-To-Debug.md new file mode 100644 index 0000000..9dffcec --- /dev/null +++ b/es/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -0,0 +1,21 @@ +# Aprende a depurar +[//]: # (Version:1.0.0) +Depurar es la piedra angular de ser un programador. El primer significado del verbo "depurar" es eliminar errores, pero el significado que realmente importa es ver la ejecución de un programa examinándolo. Un programador que no puede depurar de manera efectiva está ciego. + +Los idealistas, aquellos que creen que el diseño, el análisis, la teoría de la complejidad y cosas por el estilo son más fundamentales que la depuración, no son programadores en activo. El programador en activo no vive en un mundo ideal. Incluso si eres perfecto, estás rodeado y debes interactuar con código escrito por grandes empresas de software, organizaciones como GNU y tus colegas. La mayoría de este código es imperfecto y está imperfectamente documentado. Sin la capacidad de obtener visibilidad en la ejecución de este código, el menor tropiezo te dejará permanentemente atrás. A menudo, esta visibilidad solo se puede obtener mediante experimentación, es decir, depuración. + +La depuración se trata de la ejecución de programas, no de los programas en sí mismos. Si compras algo a una gran empresa de software, por lo general no llegas a ver el programa. Pero aún así, surgirán situaciones en las que el código no cumple con la documentación (hacer que tu máquina entera se bloquee es un ejemplo común y espectacular) o donde la documentación no dice nada. Más comúnmente, cometes un error, examinas el código que escribiste y no tienes idea de cómo puede estar ocurriendo el error. Inevitablemente, esto significa que alguna suposición que estás haciendo no es del todo correcta o que surge alguna condición que no anticipaste. A veces, el truco mágico de mirar fijamente el código fuente funciona. Cuando no lo hace, debes depurar. + +Para obtener visibilidad en la ejecución de un programa, debes ser capaz de ejecutar el código y observar algo al respecto. A veces esto es visible, como lo que se muestra en una pantalla o el intervalo de tiempo entre dos eventos. En muchos otros casos, implica cosas que no están destinadas a ser visibles, como el estado de algunas variables dentro del código, qué líneas de código se están ejecutando realmente o si ciertas afirmaciones se mantienen en una estructura de datos complicada. Estas cosas ocultas deben ser reveladas. + +Las formas comunes de examinar el "interior" de un programa en ejecución se pueden categorizar de la siguiente manera: + +- Usando una herramienta de depuración, +- Printlining: Haciendo una modificación temporal al programa, generalmente agregando líneas que imprimen información, y +- Logging: Creando una ventana permanente en la ejecución del programa en forma de un registro. + +Las herramientas de depuración son maravillosas cuando son estables y están disponibles, pero la inserción de líneas de impresión (printlining) y el registro (logging) son aún más importantes. Las herramientas de depuración a menudo quedan rezagadas con respecto al desarrollo del lenguaje, por lo que es posible que no estén disponibles en un momento dado. Además, debido a que la herramienta de depuración puede cambiar sutilmente la forma en que se ejecuta el programa, puede que no siempre sea práctica. Finalmente, hay algunos tipos de depuración, como verificar una afirmación contra una estructura de datos grande, que requieren escribir código y cambiar la ejecución del programa. Es bueno saber cómo usar herramientas de depuración cuando son estables, pero es fundamental poder emplear los otros dos métodos. + +Algunos principiantes temen la depuración cuando requiere modificar el código. Esto es comprensible, es un poco como una cirugía exploratoria. Pero debes aprender a tocar el código y hacerlo saltar; debes aprender a experimentar con él y comprender que nada de lo que hagas temporalmente lo empeorará. Si sientes este miedo, busca a un mentor; perdemos a muchos buenos programadores en el delicado inicio de su aprendizaje debido a este miedo. + +Siguiente [¿Cómo depurar dividiendo el espacio del problema?](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/es/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md b/es/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md new file mode 100644 index 0000000..11e06cf --- /dev/null +++ b/es/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -0,0 +1,16 @@ +# ¿Cómo depurar dividiendo el espacio del problema? +[//]: # (Version:1.0.0) + +Depurar es divertido, porque comienza con un misterio. Piensas que debería hacer algo, pero en cambio hace algo diferente. No siempre es tan simple; cualquier ejemplo que pueda dar será más artificial en comparación con lo que a veces sucede en la práctica. Depurar requiere creatividad e ingenio. Si hay una clave única para depurar, es utilizar la técnica de dividir y conquistar en el misterio. + +Supongamos, por ejemplo, que creaste un programa que debería realizar diez cosas en una secuencia. Cuando lo ejecutas, se bloquea. Como no lo programaste para que se bloqueara, ahora tienes un misterio. Cuando miras la salida, ves que las primeras siete cosas de la secuencia se ejecutaron con éxito. Las últimas tres no son visibles en la salida, así que ahora tu misterio es más pequeño: 'Se bloqueó en la cosa #8, #9 o #10'. + +¿Puedes diseñar un experimento para ver en qué cosa se bloqueó? Claro. Puedes usar un depurador o podemos agregar declaraciones de impresión (o su equivalente en el lenguaje en el que estás trabajando) después de #8 y #9. Cuando lo ejecutemos nuevamente, nuestro misterio será más pequeño, como 'Se bloqueó en la cosa #9'. Encuentro que tener en cuenta exactamente cuál es el misterio en cualquier momento ayuda a mantener el enfoque. Cuando varias personas trabajan juntas bajo presión en un problema, es fácil olvidar cuál es el misterio más importante. + +La clave para dividir y conquistar como técnica de depuración es la misma que para el diseño de algoritmos: siempre y cuando dividas bien el misterio por la mitad, no tendrás que dividirlo muchas veces y depurarás rápidamente. Pero, ¿cuál es la mitad de un misterio? Aquí es donde entra la verdadera creatividad y experiencia. + +Para un principiante real, el espacio de todos los posibles errores parece abarcar cada línea del código fuente. No tienes la visión que desarrollarás más adelante para ver las otras dimensiones del programa, como el espacio de las líneas ejecutadas, la estructura de datos, la gestión de memoria, la interacción con el código externo, el código riesgoso y el código simple. Para el programador experimentado, estas otras dimensiones forman un modelo mental imperfecto pero muy útil de todas las cosas que pueden salir mal. Contar con ese modelo mental es lo que ayuda a encontrar efectivamente el punto medio del misterio. + +Una vez que hayas subdividido equitativamente el espacio de todo lo que puede salir mal, debes tratar de decidir en qué espacio se encuentra el error. En el caso sencillo en el que el misterio es: "¿Qué línea desconocida hace que mi programa se bloquee?", puedes preguntarte: "¿Se ejecuta la línea desconocida antes o después de esta línea que juzgo que se ejecuta en el medio del programa en ejecución?" Por lo general, no tendrás la suerte de saber que el error existe en una sola línea, o incluso en un solo bloque. A menudo, el misterio será más como: "O bien hay un puntero en ese gráfico que apunta al nodo incorrecto, o mi algoritmo que suma las variables en ese gráfico no funciona". En ese caso, es posible que debas escribir un pequeño programa para verificar que los punteros en el gráfico sean correctos y así decidir qué parte del misterio subdividido se puede eliminar. + +Siguiente [¿Cómo eliminar un error?](03-How-to-Remove-an-Error.md) diff --git a/es/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md b/es/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md new file mode 100644 index 0000000..ea940fa --- /dev/null +++ b/es/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -0,0 +1,9 @@ +# ¿Cómo eliminar un error? +[//]: # (Version:1.0.0) +He separado intencionalmente el acto de examinar la ejecución de un programa del acto de corregir un error. Pero, por supuesto, depurar también significa eliminar el error. Idealmente, tendrás un entendimiento perfecto del código y llegarás a un momento de "¡Ajá!" donde verás perfectamente el error y cómo solucionarlo. Pero dado que tu programa a menudo utilizará sistemas insuficientemente documentados en los que no tienes visibilidad, esto no siempre es posible. En otros casos, el código es tan complicado que tu comprensión no puede ser perfecta. + +Al corregir un error, quieres hacer el cambio más pequeño que solucione el error. Puedes notar otras cosas que necesitan mejoras, pero no las corrijas al mismo tiempo. Intenta emplear el método científico de cambiar solo una cosa a la vez. El mejor proceso para esto es poder reproducir fácilmente el error, luego implementar tu corrección y volver a ejecutar el programa para observar que el error ya no existe. Por supuesto, a veces es necesario cambiar más de una línea, pero aún así debes aplicar conceptualmente un cambio único y atómico para corregir el error. + +A veces, hay varios errores que parecen ser uno solo. Depende de ti definir los errores y corregirlos uno a la vez. En ocasiones, no está claro qué debería hacer el programa o cuál era la intención del autor original. En este caso, debes ejercitar tu experiencia y juicio, asignar tu propio significado al código. Decide qué debería hacer y coméntalo o acláralo de alguna manera, luego haz que el código se ajuste a tu interpretación. Esta es una habilidad intermedia o avanzada que a veces es más difícil que escribir la función original en primer lugar, pero el mundo real a menudo es complicado. Puedes tener que corregir un sistema que no puedes reescribir. + +Siguiente [¿Cómo depurar utilizando un registro (Log)?](04-How-to-Debug-Using-a-Log.md) \ No newline at end of file diff --git a/es/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md b/es/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md new file mode 100644 index 0000000..fa6dd2b --- /dev/null +++ b/es/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -0,0 +1,13 @@ +# ¿Cómo depurar utilizando un registro (Log)? +[//]: # (Version:1.0.0) +*Registro* es la práctica de escribir un sistema de manera que produzca una secuencia de registros informativos, llamada un registro. *Printlining* es simplemente producir un registro simple, generalmente temporal. Los principiantes absolutos deben comprender y utilizar registros porque su conocimiento de programación es limitado; los arquitectos del sistema deben comprender y utilizar registros debido a la complejidad del sistema. La cantidad de información proporcionada por el registro debería ser configurable, idealmente mientras el programa se está ejecutando. En general, los registros ofrecen tres ventajas básicas: + +- Los logs pueden proporcionar información útil sobre errores que son difíciles de reproducir, como aquellos que ocurren en el entorno de producción pero que no pueden reproducirse en el entorno de prueba. +- Los logs pueden proporcionar estadísticas y datos relevantes para el rendimiento, como el tiempo transcurrido entre declaraciones. +- Cuando son configurables, los logs permiten capturar información general para depurar problemas específicos no anticipados sin tener que modificar y/o volver a implementar el código solo para abordar esos problemas específicos. + +La cantidad de información que se incluye en el log es siempre un compromiso entre la información y la concisión. Demasiada información hace que el log sea costoso y produce una *ceguera al desplazamiento*, dificultando encontrar la información necesaria. Muy poca información puede hacer que no contenga lo necesario. Por esta razón, hacer configurable lo que se produce en el log es muy útil. Típicamente, cada registro en el log identificará su posición en el código fuente, el hilo que lo ejecutó si es aplicable, el tiempo exacto de ejecución y, comúnmente, una pieza adicional de información útil, como el valor de alguna variable, la cantidad de memoria libre, el número de objetos de datos, etc. Estas declaraciones de log están distribuidas por todo el código fuente, especialmente en los puntos de funcionalidad principales y alrededor del código riesgoso. Cada declaración puede recibir un nivel y solo producirá un registro si el sistema está configurado actualmente para producir ese nivel. Debe diseñar las declaraciones de log para abordar problemas que anticipa. Anticipe la necesidad de medir el rendimiento. + +Si tiene un log permanente, la impresión temporal ahora se puede hacer en términos de los registros del log, y algunas de las declaraciones de depuración probablemente se agregarán permanentemente al sistema de registro. + +Siguiente [¿Cómo entender problemas de rendimiento?](05-How-to-Understand-Performance-Problems.md) diff --git a/es/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md b/es/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md new file mode 100644 index 0000000..73e3dc2 --- /dev/null +++ b/es/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -0,0 +1,11 @@ +# ¿Cómo entender problemas de rendimiento? +[//]: # (Version:1.0.0) +Aprender a entender el rendimiento de un sistema en ejecución es inevitable por la misma razón que aprender a depurar. Incluso si comprendes perfectamente el costo preciso del código que escribes, tu código hará llamadas a otros sistemas de software sobre los que tienes poco control o visibilidad. Sin embargo, en la práctica, los problemas de rendimiento son un poco diferentes y un poco más fáciles que la depuración en general. + +Supongamos que tú o tus clientes consideran que un sistema o un subsistema es demasiado lento. Antes de intentar acelerarlo, debes construir un modelo mental de por qué es lento. Para hacer esto, puedes utilizar una herramienta de perfilado o un buen registro para descubrir dónde se está gastando realmente el tiempo u otros recursos. Existe un famoso dicho que establece que el 90% del tiempo se gastará en el 10% del código. Añadiría a eso la importancia del gasto de entrada/salida (E/S) en los problemas de rendimiento. A menudo, la mayor parte del tiempo se gasta de alguna manera en la E/S. Encontrar la E/S costosa y el 10% costoso del código es un buen primer paso para construir tu modelo mental. + +Hay muchas dimensiones para medir el rendimiento de un sistema informático y muchos recursos consumidos. El primer recurso a medir es el tiempo del reloj de pared, el tiempo total que pasa para la computación. Registrar el tiempo del reloj de pared es particularmente valioso porque puede informar sobre circunstancias impredecibles que surgen en situaciones donde otro perfilado es impracticable. Sin embargo, esto no siempre representa toda la imagen. A veces, algo que tarda un poco más pero no consume tantos segundos del procesador será mucho mejor en el entorno informático con el que realmente tienes que lidiar. De manera similar, la memoria, el ancho de banda de red, el acceso a la base de datos u otros servidores pueden, al final, ser mucho más costosos que los segundos del procesador. + +La competencia por recursos compartidos que están sincronizados puede causar bloqueo y privación. El bloqueo es la imposibilidad de avanzar debido a una sincronización incorrecta o demandas de recursos. La privación es la incapacidad para programar adecuadamente un componente. Si se puede anticipar de alguna manera, es mejor tener una forma de medir esta competencia desde el inicio de tu proyecto. Incluso si esta competencia no ocurre, es muy útil poder afirmar eso con confianza. + +Siguiente [¿Cómo solucionar problemas de rendimiento?](06-How-to-Fix-Performance-Problems.md) diff --git a/es/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md b/es/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md new file mode 100644 index 0000000..1282b64 --- /dev/null +++ b/es/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -0,0 +1,13 @@ +# ¿Cómo solucionar problemas de rendimiento? +[//]: # (Version:1.0.0) +La mayoría de los proyectos de software pueden acelerarse de 10 a 100 veces con relativamente poco esfuerzo en comparación con la velocidad que tienen al momento de su lanzamiento inicial. Bajo la presión del tiempo de llegada al mercado, es sabio y efectivo elegir una solución que haga el trabajo de manera simple y rápida, aunque menos eficientemente que alguna otra solución. Sin embargo, el rendimiento es parte de la usabilidad y a menudo debe considerarse más cuidadosamente en algún momento. + +La clave para mejorar el rendimiento de un sistema muy complicado es analizarlo lo suficientemente bien como para encontrar los *cuellos de botella*, o los lugares donde se consumen la mayoría de los recursos. No tiene mucho sentido optimizar una función que representa solo el 1% del tiempo de computación. Como regla general, debe pensarlo detenidamente antes de hacer cualquier cosa a menos que piense que hará que el sistema o una parte significativa de él sea al menos el doble de rápido. Por lo general, hay una manera de hacerlo. Considere el esfuerzo de prueba y aseguramiento de la calidad que requerirá su cambio. Cada cambio conlleva una carga de prueba, por lo que es mucho mejor tener algunos cambios importantes. + +Después de haber logrado una mejora del doble en algo, es necesario al menos reconsiderar y tal vez volver a analizar para descubrir el siguiente cuello de botella más costoso en el sistema y abordarlo para obtener otra mejora del doble. + +A menudo, los cuellos de botella en el rendimiento son un ejemplo de contar vacas contando patas y dividiendo por cuatro, en lugar de contar cabezas. Por ejemplo, he cometido errores como no proporcionar a un sistema de base de datos relacional un índice adecuado en una columna que consulto con frecuencia, lo que probablemente lo hizo al menos 20 veces más lento. Otros ejemplos incluyen realizar E/S innecesaria en bucles internos, dejar declaraciones de depuración que ya no son necesarias, asignación de memoria innecesaria y, en particular, el uso inexperto de bibliotecas y otros subsistemas que a menudo están mal documentados en cuanto al rendimiento. Este tipo de mejora a veces se llama *fruto de bajo hanging*, lo que significa que se puede recoger fácilmente para proporcionar algún beneficio. + +¿Qué haces cuando comienzas a quedarte sin "fruto de bajo colgado"? Bueno, puedes alcanzar más alto o derribar el árbol. Puedes seguir haciendo pequeñas mejoras o puedes rediseñar seriamente un sistema o un subsistema. (Esta es una gran oportunidad para usar tus habilidades como buen programador, no solo en el nuevo diseño sino también en convencer a tu jefe de que es una buena idea). Sin embargo, antes de argumentar a favor del rediseño de un subsistema, debes preguntarte si tu propuesta lo mejorará cinco a diez veces. + +Siguiente [¿Cómo optimizar bucles?](07-How-to-Optimize-Loops.md) diff --git a/es/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md b/es/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md new file mode 100644 index 0000000..ecbc672 --- /dev/null +++ b/es/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -0,0 +1,15 @@ +# ¿Cómo optimizar bucles? +[//]: # (Version:1.0.0) +En ocasiones, te encontrarás con bucles o funciones recursivas que tardan mucho tiempo en ejecutarse y son cuellos de botella en tu producto. Antes de intentar hacer que el bucle sea un poco más rápido, tómate unos minutos para considerar si hay alguna manera de eliminarlo por completo. ¿Podría funcionar con un algoritmo diferente? ¿Podrías calcular eso mientras calculas algo más? Si no encuentras una forma de evitarlo, entonces puedes optimizar el bucle. Esto es simple; mueve cosas hacia afuera. Al final, esto requerirá no solo ingenio sino también una comprensión del costo de cada tipo de declaración y expresión. Aquí tienes algunas sugerencias: + +- Elimina operaciones de punto flotante. +- No asignes bloques de memoria nuevos innecesariamente. +- Combina constantes. +- Mueve la entrada/salida (I/O) a un búfer. +- Evita las divisiones. +- Evita las conversiones de tipo costosas. +- Muévete con un puntero en lugar de recalcular índices. + +El costo de cada una de estas operaciones depende de tu sistema específico. En algunos sistemas, los compiladores y el hardware realizan estas acciones por ti. Un código claro y eficiente es mejor que un código que requiere entender una plataforma particular. + +Siguiente [¿Cómo manejar el costo de la entrada/salida (E/S)?](08-How-to-Deal-with-IO-Expense.md) diff --git a/es/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md b/es/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md new file mode 100644 index 0000000..abc708d --- /dev/null +++ b/es/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -0,0 +1,13 @@ +# ¿Cómo manejar el costo de la entrada/salida (E/S)? +[//]: # (Version:1.0.0) +Para muchos problemas, los procesadores son rápidos en comparación con el costo de comunicarse con un dispositivo de hardware. Este costo se suele abreviar como E/S y puede incluir el costo de red, E/S de disco, consultas a la base de datos, E/S de archivos y otros usos de hardware que no están muy cerca del procesador. Por lo tanto, construir un sistema rápido a menudo es más una cuestión de mejorar la E/S que mejorar el código en un bucle ajustado, o incluso mejorar un algoritmo. + +Hay dos técnicas muy fundamentales para mejorar la E/S: el almacenamiento en caché y la representación. El almacenamiento en caché consiste en evitar la E/S (generalmente evitando la lectura de algún valor abstracto) almacenando una copia de ese valor localmente para que no se realice ninguna E/S para obtener el valor. La primera clave para la caché es dejar en claro cuál es el dato principal y cuáles son copias. Solo hay un dato principal, punto. El almacenamiento en caché conlleva el peligro de que la copia a veces no puede reflejar los cambios en el dato principal instantáneamente. + +La representación es el enfoque de hacer que la E/S sea más económica mediante la representación más eficiente de los datos. Esto a menudo entra en tensión con otras demandas, como la legibilidad humana y la portabilidad. + +Las representaciones a menudo se pueden mejorar en un factor de dos o tres desde su primera implementación. Las técnicas para hacer esto incluyen el uso de una representación binaria en lugar de una legible por humanos, transmitir un diccionario de símbolos junto con los datos para que no sea necesario codificar símbolos largos, y, en el extremo, cosas como la codificación de Huffman. + +Una tercera técnica que a veces es posible es mejorar la localidad de referencia acercando la computación a los datos. Por ejemplo, si estás leyendo algunos datos de una base de datos y calculando algo simple a partir de ellos, como una suma, intenta que el servidor de la base de datos lo haga por ti. Esto depende en gran medida del tipo de sistema con el que estás trabajando, pero deberías explorarlo. + +Siguiente [¿Cómo gestionar la memoria?](09-How-to-Manage-Memory.md) \ No newline at end of file diff --git a/es/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md b/es/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md new file mode 100644 index 0000000..babc86c --- /dev/null +++ b/es/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -0,0 +1,15 @@ +# ¿Cómo gestionar la memoria? +[//]: # (Version:1.0.0) +La memoria es un recurso precioso del cual no te puedes permitir quedarse sin. Puedes ignorarlo por un tiempo, pero eventualmente tendrás que decidir cómo gestionar la memoria. + +El espacio que necesita persistir más allá del alcance de una única subrutina se llama a menudo asignado en el montón (*heap allocated*). Un trozo de memoria es inútil, de ahí *basura*, cuando nada se refiere a él. Dependiendo del sistema que uses, es posible que debas desasignar explícitamente la memoria tú mismo cuando esté a punto de convertirse en basura. Con mayor frecuencia, puedes usar un sistema que proporciona un recolector de basura (*garbage collector*). Un recolector de basura se da cuenta de la basura y libera su espacio sin ninguna acción requerida por el programador. La recolección de basura es maravillosa: disminuye los errores y aumenta la brevedad y concisión del código de manera económica. Úsalo cuando puedas. + +Pero incluso con la recolección de basura, puedes llenar toda la memoria con basura. Un error clásico es usar una tabla hash como caché y olvidar quitar las referencias en la tabla hash. Dado que la referencia permanece, el referente no es recopilable pero es inútil. Esto se llama una fuga de memoria (memory leak). Deberías buscar y corregir las fugas de memoria temprano. Si tienes sistemas de larga duración, la memoria puede nunca agotarse durante las pruebas, pero se agotará durante el uso del usuario. + +La creación de nuevos objetos es moderadamente costosa en cualquier sistema. Sin embargo, la memoria asignada directamente en las variables locales de una subrutina suele ser barata porque la política para liberarla puede ser muy simple. Deberías evitar la creación innecesaria de objetos. + +Un caso importante ocurre cuando puedes definir un límite superior en el número de objetos que necesitarás al mismo tiempo. Si todos estos objetos ocupan la misma cantidad de memoria, es posible que puedas asignar un solo bloque de memoria, o un búfer, para contenerlos a todos. Los objetos que necesitas pueden asignarse y liberarse dentro de este búfer en un patrón de rotación establecido, por lo que a veces se le llama búfer circular. Esto suele ser más rápido que la asignación en el montón (heap allocation). + +A veces, debes liberar explícitamente el espacio asignado para que pueda volver a asignarse en lugar de depender de la recolección de basura. Luego, debes aplicar inteligencia cuidadosa a cada fragmento de memoria asignada y diseñar una forma de liberarla en el momento adecuado. El método puede diferir para cada tipo de objeto que creas. Debes asegurarte de que cada ejecución de una operación de asignación de memoria sea coincidente con una operación de desasignación de memoria eventualmente. Esto es tan difícil que los programadores a menudo simplemente implementan una forma rudimentaria de recolección de basura, como el recuento de referencias, para hacer esto por ellos. + +Siguiente [¿Cómo manejar errores intermitentes?](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/es/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md b/es/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md new file mode 100644 index 0000000..1556db3 --- /dev/null +++ b/es/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -0,0 +1,17 @@ +# ¿Cómo manejar errores intermitentes? +[//]: # (Version:1.0.0) +El error intermitente es un primo del tipo de error del escorpión invisible de 50 pies de altura del espacio exterior. Esta pesadilla ocurre tan raramente que es difícil de observar, pero lo suficientemente seguido como para no poder ignorarla. No se puede depurar porque no se puede encontrar. + +Aunque después de 8 horas empezarás a dudarlo, el error intermitente tiene que obedecer las mismas leyes de la lógica que todo lo demás. Lo que lo hace difícil es que ocurre solo bajo condiciones desconocidas. Intenta registrar las circunstancias bajo las cuales ocurre el error para que puedas adivinar cuál es la variabilidad real. La condición puede estar relacionada con los valores de los datos, como ‘Esto solo sucede cuando ingresamos *Wyoming* como un valor’. Si eso no es la fuente de la variabilidad, el siguiente sospechoso debería ser una concurrencia mal sincronizada. + +Intenta, intenta, intenta reproducir el error de manera controlada. Si no puedes reproducirlo, coloca una trampa para él construyendo un sistema de registro, uno especial si es necesario, que pueda registrar lo que crees que necesitas cuando realmente ocurra. Resignate a que si el error solo ocurre en producción y no a tu antojo, este puede ser un proceso largo. Las pistas que obtienes del registro pueden no proporcionar la solución, pero pueden darte suficiente información para mejorar el registro. El sistema de registro mejorado puede tardar mucho tiempo en implementarse en producción. Luego, debes esperar a que el error vuelva a ocurrir para obtener más información. Este ciclo puede continuar durante algún tiempo. + +El error intermitente más estúpido que creé fue en una implementación multiproceso de un lenguaje de programación funcional para un proyecto de clase. Me aseguré muy cuidadosamente de la evaluación concurrente correcta del programa funcional, buena utilización de todas las CPU disponibles (ocho, en este caso). Simplemente olvidé sincronizar el recolector de basura. El sistema podía ejecutarse durante mucho tiempo, a menudo terminando cualquier tarea que comenzará, antes de que algo notable saliera mal. Me da vergüenza admitir que había empezado a cuestionar el hardware antes de que mi error se hiciera evidente. + +En el trabajo, recientemente tuvimos un error intermitente que nos llevó varias semanas encontrar. Tenemos servidores de aplicaciones multiproceso en Java™ detrás de servidores web Apache™. Para mantener vueltas de página rápidas, realizamos todas las operaciones de entrada/salida en un pequeño conjunto de cuatro subprocesos separados de los subprocesos de cambio de página. De vez en cuando, estos aparentemente se ‘quedaban atascados’ y dejaban de hacer algo útil, hasta donde nuestras bitácoras nos permitían saber, durante horas. Dado que teníamos cuatro subprocesos, esto no era en sí mismo un problema gigante, a menos que los cuatro se quedarán atascados. Luego, las colas vaciadas por estos subprocesos llenarían rápidamente toda la memoria disponible y harían que nuestro servidor se bloqueará. Nos llevó aproximadamente una semana entender esto, y aún no sabíamos qué lo causaba, cuándo o incluso qué estaban haciendo los subprocesos cuando se quedaban ‘atascados’. + +Esto ilustra algunos riesgos asociados con el software de terceros. Estábamos utilizando un código con licencia que elimina las etiquetas HTML del texto. Aunque teníamos el código fuente (¡gracias a Dios!), no lo habíamos estudiado detenidamente hasta que, al aumentar el registro en nuestros servidores, finalmente nos dimos cuenta de que los subprocesos de correo electrónico se quedaban atascados en este problemático código con licencia. + +El programa funcionaba bien excepto en algunos textos largos y poco comunes. En estos textos, el código era cuadrático o peor. Esto significa que el tiempo de procesamiento era proporcional al cuadrado de la longitud del texto. Si estos textos ocurrieran comúnmente, habríamos encontrado el error de inmediato. Si nunca hubieran ocurrido en absoluto, nunca habríamos tenido un problema. Como sucedió, nos llevó semanas finalmente entender y resolver el problema. + +Siguiente [¿Cómo aprender habilidades de diseño?](11-How-to-Learn-Design-Skills.md) diff --git a/es/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md b/es/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md new file mode 100644 index 0000000..c13ca39 --- /dev/null +++ b/es/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -0,0 +1,9 @@ +# ¿Cómo aprender habilidades de diseño? +[//]: # (Version:1.0.0) +Para aprender a diseñar software, estudia la acción de un mentor al estar físicamente presente cuando están diseñando. Luego, estudia software bien escrito. Después de eso, puedes leer algunos libros sobre las últimas técnicas de diseño. + +Luego, debes hacerlo tú mismo. Comienza con un proyecto pequeño. Cuando finalmente hayas terminado, considera cómo falló o tuvo éxito el diseño y en qué te desviaste de tu concepción original. Luego pasa a proyectos más grandes, idealmente en colaboración con otras personas. El diseño es una cuestión de juicio que lleva años adquirir. Un programador inteligente puede aprender los conceptos básicos adecuadamente en dos meses y puede mejorar a partir de ahí. + +Es natural y útil desarrollar tu propio estilo, pero recuerda que el diseño es un arte, no una ciencia. Las personas que escriben libros sobre el tema tienen un interés personal en hacer que parezca científico. No te vuelvas dogmático sobre estilos de diseño particulares. + +Siguiente [¿Cómo realizar experimentos?](12-How-to-Conduct-Experiments.md) diff --git a/es/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md b/es/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md new file mode 100644 index 0000000..dbd8c5d --- /dev/null +++ b/es/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -0,0 +1,23 @@ +# ¿Cómo realizar experimentos? +[//]: # (Version:1.0.0) +El difunto y gran Edsger Dijkstra ha explicado elocuentemente que la informática no es una ciencia experimental [ExpCS] y no depende de las computadoras electrónicas. Como él lo expresa refiriéndose a la década de 1960 [Knife], + +> ...se hizo el daño: el tema se dio a conocer como "ciencia de la computación", que, en realidad, es como referirse a la cirugía como "ciencia del cuchillo", y se implantó firmemente en la mente de las personas que la ciencia informática trata sobre máquinas y su equipo periférico. + +La programación no debería ser una ciencia experimental, pero la mayoría de los programadores en activo no tienen el lujo de participar en lo que Dijkstra entiende por ciencia informática. Debemos trabajar en el ámbito de la experimentación, al igual que algunos, pero no todos, los físicos lo hacen. Si treinta años después se puede programar sin experimentación, será un gran logro de la Ciencia de la Computación. + +Los tipos de experimentos que tendrás que realizar incluyen: + +- Probar sistemas con ejemplos pequeños para verificar que se ajustan a la documentación o para entender su respuesta cuando no hay documentación, +- Probar pequeños cambios de código para ver si realmente soluciona un error. +- Medir el rendimiento de un sistema bajo dos condiciones diferentes debido al conocimiento imperfecto de sus características de rendimiento, +- Verificar la integridad de los datos y +- Recopilar estadísticas que puedan dar pistas sobre la solución a errores difíciles o difíciles de repetir. + +No creo que en este ensayo pueda explicar el diseño de experimentos; tendrás que estudiar y practicar. Sin embargo, puedo ofrecer dos consejos. + +En primer lugar, trata de ser muy claro acerca de tu hipótesis o la afirmación que estás tratando de probar. También ayuda escribir la hipótesis, especialmente si te encuentras confundido o estás trabajando con otras personas. + +A menudo te encontrarás teniendo que diseñar una serie de experimentos, cada uno de los cuales se basa en el conocimiento adquirido del último experimento. Por lo tanto, debes diseñar tus experimentos para proporcionar la mayor información posible. + +Siguiente [Habilidades de equipo: ¿Por qué es importante la estimación?](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/es/1-Beginner/README.md b/es/1-Beginner/README.md new file mode 100644 index 0000000..733389a --- /dev/null +++ b/es/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. Principiante +[//]: # (Version:1.0.0) +- Habilidades Personales + - [Aprender a Depurar](Personal-Skills/01-Learn-To-Debug.md) + - [¿Cómo depurar dividiendo el espacio del problema?](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [¿Cómo eliminar un error?](Personal-Skills/03-How-to-Remove-an-Error.md) + - [¿Cómo Depurar Utilizando un Registro (Log)?](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [¿Cómo Entender Problemas de Rendimiento?](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [¿Cómo Solucionar Problemas de Rendimiento?](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [¿Cómo Optimizar Bucles?](Personal-Skills/07-How-to-Optimize-Loops.md) + - [¿Cómo Manejar el Costo de la Entrada/Salida (E/S)?](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [¿Cómo Gestionar la Memoria?](Personal-Skills/09-How-to-Manage-Memory.md) + - [¿Cómo Manejar Errores Intermitentes?](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [¿Cómo Aprender Habilidades de Diseño?](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [¿Cómo Realizar Experimentos?](Personal-Skills/12-How-to-Conduct-Experiments.md) +- Habilidades de Equipo + - [¿Por qué es importante la estimación?](Team-Skills/01-Why-Estimation-is-Important.md) + - [¿Cómo estimar el tiempo de programación?](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [¿Cómo encontrar información?](Team-Skills/03-How-to-Find-Out-Information.md) + - [¿Cómo utilizar a las personas como fuentes de información?](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [¿Cómo documentar de manera inteligente?](Team-Skills/05-How-to-Document-Wisely.md) + - [¿Cómo trabajar con un código deficiente?](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [¿Cómo Utilizar el Control de Código Fuente?](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [¿Cómo realizar pruebas unitarias?](Team-Skills/08-How-to-Unit-Test.md) + - [Tomarse descansos cuando te sientes bloqueado](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [¿Cómo reconocer cuándo es hora de ir a casa?](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [¿Cómo lidiar con personas difíciles?](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/es/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md b/es/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md new file mode 100644 index 0000000..138953d --- /dev/null +++ b/es/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -0,0 +1,15 @@ +# ¿Por qué es importante la estimación? +[//]: # (Version:1.0.0) +Para obtener un sistema de software en funcionamiento y en uso activo lo más rápido posible, se requiere no solo planificar el desarrollo, sino también planificar la documentación, la implementación y la comercialización. En un proyecto comercial, también se necesitan ventas y finanzas. Sin previsibilidad del tiempo de desarrollo, es imposible planificar eficazmente estos aspectos. + +Una buena estimación proporciona previsibilidad. A los gerentes les encanta, como debería ser. El hecho de que sea imposible, tanto teórica como prácticamente, predecir con precisión cuánto tiempo tomará desarrollar software a menudo se pasa por alto. Nos piden hacer esta tarea imposible todo el tiempo, y debemos enfrentarla honestamente. Sin embargo, sería deshonesto no admitir la imposibilidad de esta tarea y, cuando sea necesario, explicarla. Existe mucho margen para la falta de comunicación sobre las estimaciones, ya que las personas tienden a pensar con optimismo en la frase: [aquí deberías completar la oración si es parte del texto original: + +> Estimo que, si realmente entiendo el problema, hay aproximadamente un 50% de probabilidad de que hayamos terminado en cinco semanas (si nadie nos molesta durante ese tiempo). + +really means: + +> Prometo tener todo listo dentro de cinco semanas a partir de ahora. + +Este problema común de interpretación requiere que discutas explícitamente lo que significa la estimación con tu jefe o cliente, como si fueran una persona no familiarizada con el tema. Vuelve a expresar tus suposiciones, por más obvias que parezcan para ti. + +Siguiente [¿Cómo estimar el tiempo de programación?](02-How-to-Estimate-Programming-Time.md) diff --git a/es/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md b/es/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md new file mode 100644 index 0000000..dbcd670 --- /dev/null +++ b/es/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -0,0 +1,21 @@ +# ¿Cómo estimar el tiempo de programación? +[//]: # (Version:1.0.0) +La estimación requiere práctica. También requiere trabajo. Requiere tanto trabajo que puede ser una buena idea estimar el tiempo que tomará hacer la estimación, especialmente si te piden que estimes algo grande. + +Cuando te piden que proporciones una estimación de algo grande, lo más honesto es hacer una pausa. La mayoría de los ingenieros son entusiastas y ansían complacer, y hacer una pausa ciertamente desagradará a quienes están a la espera. Pero una estimación instantánea probablemente no será precisa ni honesta. + +Mientras te tomas tu tiempo, puede ser posible considerar hacer o prototipar la tarea. Si la presión política lo permite, esta es la forma más precisa de producir la estimación y hace un progreso real. + +Cuando no es posible tomarse el tiempo para una investigación, debes establecer claramente el significado de la estimación. Reafirma ese significado como la primera y última parte de tu estimación por escrito. Prepara una estimación por escrito descomponiendo la tarea en subtareas progresivamente más pequeñas hasta que cada tarea pequeña no sea de más de un día; idealmente, la mayoría debería durar solo un día. Lo más importante es no dejar nada afuera. Por ejemplo, la documentación, las pruebas, el tiempo de planificación, el tiempo de comunicación con otros grupos y el tiempo de vacaciones son todos muy importantes. Si pasas parte de cada día lidiando con situaciones difíciles, incluye un ítem para eso en la estimación. Esto le brinda a tu jefe visibilidad sobre en qué estás utilizando tu tiempo como mínimo, y podría conseguirte más tiempo. + +Conozco a buenos ingenieros que inflan las estimaciones implícitamente, pero recomiendo que no lo hagas. Uno de los resultados de inflar es que la confianza en ti puede disminuir. Por ejemplo, un ingeniero podría estimar tres días para una tarea que realmente cree que tomará un día. El ingeniero puede planear pasar dos días documentándolo o dos días trabajando en algún otro proyecto útil. Pero será detectable que la tarea se hizo en solo un día (si resulta ser así), y surgirá la apariencia de descuido o sobreestimación. Es mucho mejor dar una visibilidad adecuada a lo que realmente estás haciendo. Si la documentación lleva el doble de tiempo que la codificación y la estimación lo refleja, se obtiene una ventaja tremenda al hacer esto visible para el gerente. + +Realiza un ajuste explícito en lugar de forma implícita. Si una tarea probablemente llevará un día, pero podría llevar diez días si tu enfoque no funciona, indícalo de alguna manera en la estimación si es posible; si no, al menos haz un promedio ponderado según tus estimaciones de las probabilidades. Cualquier factor de riesgo que puedas identificar y al que puedas asignar una estimación debe incluirse en el cronograma. Es poco probable que una persona se enferme en una semana específica. Pero un proyecto grande con muchos ingenieros tendrá algún tiempo de enfermedad, al igual que tiempo de vacaciones. ¿Cuál es la probabilidad de un seminario de capacitación obligatorio para toda la empresa? Si se puede estimar, inclúyelo. Por supuesto, hay incertidumbres *unk-unks* (desconocidas), o unknown unknowns (Desconocidos desconocidos). Por definición, los unknown unknowns no se pueden estimar individualmente. Puedes intentar crear un ítem global para todos los unknown unknowns, o manejarlos de alguna otra manera que comuniques a tu jefe. Sin embargo, no puedes permitir que tu jefe olvide que existen, y es increíblemente fácil que una estimación se convierta en un cronograma sin tener en cuenta los unknown unknowns. + +En un entorno de equipo, debes intentar que las personas que realizarán el trabajo realicen la estimación, y debes buscar el consenso en toda el equipo sobre las estimaciones. Las habilidades, la experiencia, la preparación y la confianza de las personas varían ampliamente. Ocurre una calamidad cuando un programador hábil estima para sí misma y luego se espera que los programadores menos hábiles cumplan con esa estimación. El hecho de que todo el equipo esté de acuerdo, línea por línea, en la estimación aclara la comprensión del equipo, además de permitir la oportunidad de reasignación táctica de recursos (por ejemplo, aliviar la carga de los miembros más débiles). + +Si hay riesgos importantes que no se pueden evaluar, es tu responsabilidad afirmarlo con la suficiente fuerza para que tu gerente no se comprometa con ellos y luego se sienta avergonzado cuando ocurra el riesgo. Con suerte, en tal caso, se hará todo lo necesario para disminuir el riesgo. + +Si logras convencer a tu empresa de utilizar *Extreme Programming*, solo tendrás que estimar cosas relativamente pequeñas, lo cual es más divertido y más productivo. + +Siguiente [¿Cómo encontrar información?](03-How-to-Find-Out-Information.md) diff --git a/es/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md b/es/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md new file mode 100644 index 0000000..7368ab0 --- /dev/null +++ b/es/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -0,0 +1,19 @@ +# ¿Cómo encontrar información? +[//]: # (Version:1.0.0) +La naturaleza de lo que necesitas saber determina la forma en que debes buscarlo. + +Si necesitas información *sobre cosas concretas* que son objetivas y fáciles de verificar, como el último nivel de parche de un producto de software, pregunta a un gran número de personas de manera educada buscándolo en internet o publicando en un grupo de discusión. No busques en internet nada que tenga un tinte de opinión o interpretación subjetiva: la proporción de tonterías a verdad es demasiado alta. + +Si necesitas *conocimiento general sobre algo subjetivo*, como la historia de lo que la gente ha pensado al respecto, ve a la biblioteca (el edificio físico donde se almacenan libros). Por ejemplo, para aprender sobre matemáticas, setas o misticismo, acude a la biblioteca. + +Si necesitas saber *cómo hacer algo que no es trivial*, consigue dos o tres libros sobre el tema y léelos. Puedes aprender a hacer algo trivial, como instalar un paquete de software, desde Internet. Incluso puedes aprender cosas importantes, como buenas técnicas de programación, pero fácilmente puedes pasar más tiempo buscando y clasificando los resultados y tratando de discernir la autoridad de los resultados que el que tomaría leer la parte pertinente de un libro sólido. + +Si necesitas *información que no se espera que nadie más conozca*, por ejemplo, '¿este software completamente nuevo funciona con conjuntos de datos gigantes?', aún debes buscar en internet y en la biblioteca. Después de agotar por completo esas opciones, puedes diseñar un experimento para confirmarlo. + +Si deseas una opinión o un juicio de valor que tenga en cuenta alguna circunstancia única, habla con un experto. Por ejemplo, si quieres saber si es buena idea construir un sistema moderno de gestión de bases de datos en LISP, deberías hablar con un experto en LISP y un experto en bases de datos. + +Si quieres saber *qué tan probable es* que exista un algoritmo más rápido para una aplicación específica que aún no se ha publicado, habla con alguien que trabaje en ese campo. + +Si quieres tomar una *decisión personal que solo tú puedes tomar*, como si deberías o no iniciar un negocio, intenta poner por escrito una lista de argumentos a favor y en contra de la idea. Si eso falla, considera la adivinación. Supongamos que has estudiado la idea desde todos los ángulos, has hecho toda tu tarea, y has analizado todas las consecuencias y pros y contras en tu mente, y aún así sigues indeciso. Ahora debes seguir tu corazón y decirle a tu cerebro que se calle. La multitud de técnicas de adivinación disponibles son muy útiles para determinar tus propios deseos semi-conscientes, ya que cada una presenta un patrón completo, ambiguo y aleatorio al que tu propio subconsciente asignará significado. + +Siguiente [¿Cómo utilizar a las personas como fuentes de información?](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/es/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md b/es/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md new file mode 100644 index 0000000..adc4ab2 --- /dev/null +++ b/es/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -0,0 +1,15 @@ +# ¿Cómo utilizar a las personas como fuentes de información? +[//]: # (Version:1.0.0) +Respetar el tiempo de cada persona y equilibrarlo con el tuyo es fundamental. Hacer una pregunta a alguien logra mucho más que simplemente recibir la respuesta. La persona aprende acerca de ti, tanto disfrutando de tu presencia como escuchando la pregunta en particular. De la misma manera, tú aprendes acerca de la persona y es posible que obtengas la respuesta que buscas. Esto suele ser mucho más importante que la propia pregunta. + +Sin embargo, el valor de esto disminuye a medida que lo haces más frecuentemente. Estás utilizando el bien más preciado que tiene una persona: su tiempo. Los beneficios de la comunicación deben sopesarse contra los costos. Además, los costos y beneficios particulares obtenidos difieren de una persona a otra. Creo firmemente que un ejecutivo con 100 personas a cargo debería pasar cinco minutos al mes hablando con cada persona en su organización, lo que sería aproximadamente el 5% de su tiempo. Pero diez minutos podrían ser demasiado, y cinco minutos son demasiados si tienen mil empleados. La cantidad de tiempo que dedicas a hablar con cada persona en tu organización depende de su función (más que de su posición). Deberías hablar más con tu jefe que con el jefe de tu jefe, pero deberías hablar un poco con el jefe de tu jefe. Puede ser incómodo, pero creo que tienes el deber de hablar un poco con todos tus superiores cada mes, sin importar qué. + +La regla básica es que todos se benefician al hablar contigo un poco, y cuanto más hablen contigo, menos beneficio obtendrán. Es tu trabajo proporcionarles este beneficio y obtener el beneficio de comunicarte con ellos, manteniendo un equilibrio con el tiempo invertido. + +Es importante respetar tu propio tiempo. Si hablar con alguien, incluso si les costará tiempo, te ahorrará mucho tiempo, entonces deberías hacerlo a menos que creas que su tiempo es más valioso que el tuyo, para la tribu, por ese factor. + +Un ejemplo extraño de esto es el becario de verano. No se espera que un becario de verano en una posición altamente técnica logre mucho; se espera que moleste a todos. Entonces, ¿por qué se tolera esto? Porque los molestados están recibiendo algo importante del becario. Tienen la oportunidad de lucirse un poco. Tienen la oportunidad de escuchar algunas ideas nuevas, tal vez; tienen la oportunidad de ver las cosas desde una perspectiva diferente. También pueden estar intentando reclutar al becario, pero incluso si no es el caso, hay mucho que ganar. + +Deberías pedirle a la gente un poco de su sabiduría y juicio siempre que honestamente creas que tienen algo que decir. Esto los halaga y aprenderás algo y les enseñarás algo. Un buen programador no suele necesitar el consejo de un Vicepresidente de Ventas, pero si alguna vez lo necesitas, asegúrate de pedirlo. Una vez pedí escuchar algunas llamadas de ventas para entender mejor el trabajo de nuestro personal de ventas. Esto no llevó más de 30 minutos, pero creo que ese pequeño esfuerzo dejó una impresión en el equipo de ventas. + +Siguiente [¿Cómo documentar de manera inteligente?](05-How-to-Document-Wisely.md) \ No newline at end of file diff --git a/es/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md b/es/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md new file mode 100644 index 0000000..55a972e --- /dev/null +++ b/es/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -0,0 +1,20 @@ +# ¿Cómo documentar de manera inteligente? +[//]: # (Version:1.0.0) +La vida es demasiado corta para escribir basura que nadie va a leer; si escribes basura, nadie la leerá. Por lo tanto, un poco de buena documentación es lo mejor. Los gerentes a menudo no entienden esto, porque incluso una mala documentación les da una falsa sensación de seguridad de que no dependen de sus programadores. Si alguien insiste absolutamente en que escribas documentación verdaderamente inútil, di 'sí' y comienza discretamente a buscar un trabajo mejor. + +No hay nada tan efectivo como incluir una estimación precisa del tiempo que tomará producir buena documentación en una estimación para reducir la demanda de documentación. La verdad es fría y dura: la documentación, al igual que las pruebas, puede llevar muchas veces más tiempo que desarrollar código. + +Escribir buena documentación es, ante todo, escribir bien. Te sugiero que encuentres libros sobre escritura, los estudies y practiques. Pero incluso si eres un mal escritor o tienes poco dominio del idioma en el que debes documentar, la Regla de Oro es todo lo que realmente necesitas: 'Haz a los demás lo que te gustaría que te hicieran a ti'. Tómate el tiempo para pensar realmente en quién leerá tu documentación, lo que necesitan obtener de ella y cómo puedes enseñárselo. Si haces eso, serás un escritor de documentación por encima del promedio y un buen programador. + +Cuando se trata de documentar el código en sí, en lugar de producir documentos que realmente puedan ser leídos por no programadores, los mejores programadores que he conocido comparten un sentimiento universal: escribe código autoexplicativo y documenta el código solo en los lugares en los que no puedes hacerlo claro escribiendo el código mismo. Hay dos buenas razones para esto. En primer lugar, cualquier persona que necesite ver documentación a nivel de código, en la mayoría de los casos, podrá y preferirá leer el código de todos modos. Es cierto que esto parece más fácil para el programador experimentado que para el principiante. Más importante aún, sin embargo, es que el código y la documentación no pueden ser inconsistentes si no hay documentación. El código fuente puede ser, en el peor de los casos, incorrecto y confuso. La documentación, si no está escrita perfectamente, puede mentir, y eso es mil veces peor. + +Esto no facilita las cosas al programador responsable. ¿Cómo se escribe código autoexplicativo? ¿Qué significa eso siquiera? Significa: + +- Escribir código sabiendo que alguien tendrá que leerlo. +- Aplicar la regla de oro. +- Elegir una solución que sea directa, incluso si podrías usar otra solución más rápida. +- Sacrificar pequeñas optimizaciones que oscurecen el código. +- Pensar en el lector y dedicar parte de tu tiempo precioso para facilitarle la comprensión. +- Nunca usar un nombre de función como foo, bar o doIt. + +Siguiente [¿Cómo trabajar con un código deficiente?](06-How-to-Work-with-Poor-Code.md) \ No newline at end of file diff --git a/es/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md b/es/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md new file mode 100644 index 0000000..bcc39d5 --- /dev/null +++ b/es/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -0,0 +1,11 @@ +# ¿Cómo trabajar con un código deficiente? +[//]: # (Version:1.0.0) +Es muy común tener que trabajar con código de baja calidad que alguien más ha escrito. No pienses demasiado mal de ellos, sin embargo, hasta que hayas estado en su lugar. Es posible que les hayan pedido muy conscientemente que hagan algo rápidamente para cumplir con la presión del cronograma. Independientemente, para trabajar con código poco claro, debes entenderlo. Entenderlo lleva tiempo de aprendizaje, y ese tiempo tendrá que salir de algún cronograma, en algún lugar, y debes insistir en ello. Para entenderlo, tendrás que leer el código fuente. Probablemente tendrás que experimentar con él. + +Este es un buen momento para documentar, incluso si es solo para ti, porque el acto de intentar documentar el código te obligará a considerar ángulos que quizás no hayas tenido en cuenta, y el documento resultante puede ser útil. Mientras haces esto, considera qué sería necesario para reescribir parte o todo el código. ¿Realmente ahorraría tiempo reescribir parte de él? ¿Podrías confiar más en él si lo reescribieras? Ten cuidado con la arrogancia aquí. Si lo reescribes, será más fácil para ti manejarlo, pero ¿realmente será más fácil para la siguiente persona que tenga que leerlo? Si lo reescribes, ¿cuál será la carga de pruebas? ¿Superará la necesidad de volver a probarlo cualquier beneficio que se pueda obtener? + +En cualquier estimación que hagas para trabajar con código que no escribiste, la calidad de ese código debería afectar tu percepción del riesgo de problemas y desconocidos. + +Es importante recordar que la abstracción y la encapsulación, dos de las mejores herramientas de un programador, son particularmente aplicables al código deficiente. Es posible que no puedas rediseñar un bloque grande de código, pero si puedes agregar cierta cantidad de abstracción, puedes obtener algunos de los beneficios de un buen diseño sin rehacer todo el desorden. En particular, puedes intentar aislar las partes que son especialmente malas para que puedan ser rediseñadas de forma independiente. + +Siguiente [¿Cómo Utilizar el Control de Código Fuente?](07-How-to-Use-Source-Code-Control.md) \ No newline at end of file diff --git a/es/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md b/es/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md new file mode 100644 index 0000000..8740658 --- /dev/null +++ b/es/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -0,0 +1,9 @@ +# ¿Cómo Utilizar el Control de Código Fuente? +[//]: # (Version:1.0.0) +Los sistemas de control de código fuente (también conocidos como sistemas de control de versiones) te permiten gestionar proyectos de manera efectiva. Son muy útiles para una persona y esenciales para un grupo. Siguen todos los cambios en diferentes versiones para que nunca se pierda código y se pueda asignar significado a los cambios. Con un sistema de control de código fuente, puedes crear código temporal y de depuración con confianza, ya que el código que modificas se mantiene cuidadosamente separado del código oficial comprometido que se compartirá con el equipo o se lanzará. + +Tardé en apreciar los beneficios de los sistemas de control de código fuente, pero ahora no viviría sin uno, incluso en un proyecto individual. Generalmente son necesarios cuando tienes un equipo trabajando en la misma base de código. Sin embargo, tienen otra gran ventaja: fomentan pensar en el código como un sistema orgánico en crecimiento. Dado que cada cambio se marca como una nueva revisión con un nuevo nombre o número, uno comienza a pensar en el software como una serie visible y progresiva de mejoras. Creo que esto es especialmente útil para principiantes. + +Una buena técnica para utilizar un sistema de control de código fuente es mantenerse actualizado en todo momento, dentro de unos pocos días. El código que no se puede terminar en unos pocos días se registra, pero de una manera inactiva que no se llamará y, por lo tanto, no creará problemas para nadie más. Cometer un error que ralentiza a tus compañeros de equipo es un error grave; a menudo es tabú. + +Siguiente [¿Cómo realizar pruebas unitarias?](08-How-to-Unit-Test.md) diff --git a/es/1-Beginner/Team-Skills/08-How-to-Unit-Test.md b/es/1-Beginner/Team-Skills/08-How-to-Unit-Test.md new file mode 100644 index 0000000..1adc4ba --- /dev/null +++ b/es/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -0,0 +1,9 @@ +# ¿Cómo realizar pruebas unitarias? +[//]: # (Version:1.0.0) +Las pruebas unitarias, que consisten en probar una funcionalidad individual codificada por el equipo que la escribió, son parte del proceso de codificación, no algo diferente. Parte del diseño del código es diseñar cómo se probará. Deberías escribir un plan de pruebas, incluso si es solo una oración. A veces, la prueba será simple: '¿Se ve bien el botón?' A veces será compleja: '¿Este algoritmo de coincidencia devolvió coincidencias precisas?' + +Utiliza la verificación de afirmaciones y los controladores de prueba siempre que sea posible. Esto no solo detecta errores temprano, sino que también es muy útil más adelante y te permite eliminar misterios sobre los que de lo contrario tendrías que preocuparte. + +Los desarrolladores de Extreme Programming escriben extensamente sobre cómo realizar pruebas unitarias de manera efectiva; no puedo hacer más que recomendar sus escritos. + +Siguiente [Tomarse descansos cuando te sientes bloqueado](09-Take-Breaks-when-Stumped.md) \ No newline at end of file diff --git a/es/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md b/es/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md new file mode 100644 index 0000000..0a857c2 --- /dev/null +++ b/es/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -0,0 +1,5 @@ +# Tomarse descansos cuando te sientes bloqueado +[//]: # (Version:1.0.0) +Cuando te sientas bloqueado, toma un descanso. A veces, medito durante 15 minutos cuando estoy bloqueado y el problema se desentraña mágicamente cuando regreso a él. Una noche de sueño a veces hace lo mismo a una escala más amplia. Es posible que cambiar temporalmente a cualquier otra actividad también funcione. + +Siguiente [¿Cómo reconocer cuándo es hora de ir a casa?](10-How-to-Recognize-When-to-Go-Home.md) diff --git a/es/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md b/es/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md new file mode 100644 index 0000000..ca765f7 --- /dev/null +++ b/es/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -0,0 +1,16 @@ +# ¿Cómo reconocer cuándo es hora de ir a casa? +[//]: # (Version:1.0.0) +La programación de computadoras es una actividad que también es una cultura. El lamentable hecho es que no es una cultura que valore mucho la salud mental o física. Por razones culturales/históricas (la necesidad de trabajar por la noche en computadoras sin carga, por ejemplo) y debido a la abrumadora presión de tiempo para llegar al mercado y a la escasez de programadores, los programadores de computadoras suelen estar tradicionalmente sobrecargados. No creo que se puedan confiar todas las historias que escuchas, pero creo que 60 horas a la semana es común, y 50 es prácticamente un mínimo. Esto significa que a menudo se requiere mucho más que eso. Esto es un problema grave para un buen programador, que es responsable no solo de sí mismo sino también de sus compañeros de equipo. Tienes que reconocer cuándo irte a casa, y a veces cuándo sugerir que otras personas se vayan a casa. No puede haber reglas fijas para resolver este problema, al igual que no puede haber reglas fijas para criar a un niño, por la misma razón: cada ser humano es diferente. + +Más de 60 horas a la semana es un esfuerzo extraordinario para mí, que puedo aplicar durante períodos cortos de tiempo (aproximadamente una semana), y a veces se espera eso de mí. No sé si es justo esperar 60 horas de trabajo de una persona; ni siquiera sé si 40 horas es justo. Estoy seguro, sin embargo, de que es estúpido trabajar tanto que obtienes poco de esa hora extra de trabajo. Personalmente, para mí, eso es más de 60 horas a la semana. Personalmente, creo que un programador debería ejercer la nobleza y cargar con una carga pesada. Sin embargo, no es deber de un programador ser un tonto útil. El triste hecho es que a menudo se les pide a los programadores que sean tontos útiles para hacer un espectáculo para alguien, por ejemplo, un gerente que intenta impresionar a un ejecutivo. Los programadores a menudo sucumben a esto porque están ansiosos por complacer y no son muy buenos para decir no. Hay cuatro defensas contra esto: + +- Comunica tanto como sea posible con todos en la empresa para que nadie pueda engañar a los ejecutivos sobre lo que está sucediendo. +- Aprende a estimar y programar de manera defensiva y explícita y brinda a todos visibilidad sobre cuál es el cronograma y dónde se encuentra. +- Aprende a decir no, y dilo como equipo cuando sea necesario, y +- Renuncia si es necesario. + +La mayoría de los programadores son buenos programadores, y los buenos programadores quieren hacer mucho. Para lograrlo, tienen que gestionar su tiempo de manera efectiva. Existe una cierta cantidad de inercia mental asociada con calentarse para resolver un problema y sumergirse profundamente en él. Muchos programadores encuentran que trabajan mejor cuando tienen bloques largos e ininterrumpidos de tiempo para calentarse y concentrarse. Sin embargo, las personas deben dormir y realizar otras tareas. Cada persona debe encontrar una manera de satisfacer tanto su ritmo humano como su ritmo de trabajo. Cada programador debe hacer lo que sea necesario para obtener períodos eficientes de trabajo, como reservar ciertos días en los que solo asistirás a las reuniones más críticas. + +Desde que tengo hijos, trato de pasar algunas noches con ellos. El ritmo que mejor funciona para mí es trabajar un día muy largo, dormir en la oficina o cerca de la oficina (tengo un largo viaje de casa al trabajo), luego irme a casa lo suficientemente temprano al día siguiente para pasar tiempo con mis hijos antes de que se vayan a la cama. No me siento cómodo con esto, pero es el mejor compromiso que he podido encontrar. Ve a casa si tienes una enfermedad contagiosa. Deberías irte a casa si estás pensando en pensamientos suicidas. Deberías tomar un descanso o irte a casa si piensas en pensamientos homicidas durante más de unos segundos. Deberías enviar a alguien a casa si muestra un mal funcionamiento mental grave o signos de enfermedad mental más allá de una depresión leve. Si sientes la tentación de ser deshonesto o engañoso de una manera que normalmente no lo eres debido a la fatiga, deberías tomar un descanso. No uses cocaína o anfetaminas para combatir la fatiga. No abuses de la cafeína. + +Siguiente [¿Cómo lidiar con personas difíciles?](11-How-to-Deal-with-Difficult-People.md) diff --git a/es/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md b/es/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md new file mode 100644 index 0000000..a94f20f --- /dev/null +++ b/es/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -0,0 +1,15 @@ +# ¿Cómo lidiar con personas difíciles? +[//]: # (Version:1.0.0) +Es probable que tengas que lidiar con personas difíciles. Incluso tú mismo podrías ser una persona difícil. Si eres el tipo de persona que tiene muchos conflictos con compañeros de trabajo y figuras de autoridad, deberías apreciar la independencia que esto implica, pero trabaja en tus habilidades interpersonales sin sacrificar tu inteligencia o principios. + +Esto puede ser muy perturbador para algunos programadores que no tienen experiencia en este tipo de situaciones y cuya experiencia de vida anterior les ha enseñado patrones de comportamiento que no son útiles en el lugar de trabajo. Las personas difíciles a menudo están acostumbradas al desacuerdo y son menos afectadas por la presión social para llegar a compromisos que otros. La clave es respetarlos apropiadamente, más de lo que quisieras, pero no tanto como ellos podrían desear. + +Los programadores tienen que trabajar juntos como equipo. Cuando surge un desacuerdo, debe resolverse de alguna manera, no se puede esquivar durante mucho tiempo. Las personas difíciles a menudo son extremadamente inteligentes y tienen algo muy útil que decir. Es crucial que escuches y comprendas a la persona difícil sin prejuicios causados por la persona. La falta de comunicación es a menudo la base del desacuerdo, pero a veces se puede eliminar con mucha paciencia. Intenta mantener esta comunicación tranquila y cordial, y no aceptes provocaciones para un mayor conflicto que puedan ofrecer. Después de un período razonable de intentar entender, toma una decisión. + +No dejes que un matón te obligue a hacer algo con lo que no estás de acuerdo. Si eres el líder, haz lo que creas que es mejor. No tomes decisiones por razones personales y prepárate para explicar las razones de tu decisión. Si eres un compañero de equipo con una persona difícil, no dejes que la decisión del líder tenga un impacto personal. Si no va en tu dirección, hazlo de la otra manera de todo corazón. + +Las personas difíciles cambian y mejoran. Lo he visto con mis propios ojos, pero es muy raro. Sin embargo, todos tienen altibajos transitorios. + +Uno de los desafíos que enfrenta cada programador, pero especialmente los líderes, es mantener a la persona difícil completamente comprometida. Son más propensos a esquivar el trabajo y resistirse pasivamente que otros. + +Siguiente [Habilidades intermedias](../../2-Intermediate) diff --git a/es/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md b/es/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md new file mode 100644 index 0000000..370e417 --- /dev/null +++ b/es/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -0,0 +1,14 @@ +# ¿Cómo equilibrar la calidad contra el tiempo de desarrollo? +[//]: # (Version:1.0.0) + +El desarrollo de software siempre es un compromiso entre lo que hace el proyecto y lograr que el proyecto se complete. Sin embargo, puede que te pidan que sacrifiques la calidad para acelerar la implementación de un proyecto de una manera que vaya en contra de tus sensibilidades técnicas o comerciales. Por ejemplo, podrían pedirte que hagas algo que sea una mala práctica de ingeniería de software y que conduzca a muchos problemas de mantenimiento. + +Si esto sucede, tu primera responsabilidad es informar a tu equipo y explicar claramente el costo de la disminución de la calidad. Después de todo, tu comprensión debería ser mucho mejor que la de tu jefe. Deja claro lo que se está perdiendo y lo que se está ganando, y a qué costo se recuperará el terreno perdido en el próximo ciclo. En esto, la visibilidad proporcionada por un buen plan de proyecto debería ser útil. Si el compromiso de calidad afecta al esfuerzo de aseguramiento de calidad, señálalo (tanto a tu jefe como a las personas encargadas de la calidad). Si el compromiso de calidad conduce a que se informen más errores después del período de aseguramiento de calidad, señálalo. + +Si aún así insiste, deberías tratar de aislar la falta de calidad en componentes específicos que puedas planear reescribir o mejorar en el próximo ciclo. Explícaselo a tu equipo para que puedan planificarlo. + +NinjaProgrammer en Slashdot envió esta joya: + +> Recuerda que un buen diseño será resistente frente a implementaciones de código deficientes. Si existen buenas interfaces y abstracciones en todo el código, las reescrituras eventualmente serán mucho menos dolorosas. Si es difícil escribir código claro que sea difícil de corregir, considera qué hay de malo en el diseño central que está causando esto. + +Siguiente [¿Cómo gestionar la dependencia del sistema de software?](02-How-to-Manage-Software-System-Dependence.md) diff --git a/es/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md b/es/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md new file mode 100644 index 0000000..436add3 --- /dev/null +++ b/es/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -0,0 +1,13 @@ +# ¿Cómo gestionar la dependencia del sistema de software? +[//]: # (Version:1.0.0) +Los sistemas de software modernos tienden a depender de un gran número de componentes que pueden no estar directamente bajo tu control. Esto aumenta la productividad a través de la sinergia y la reutilización. Sin embargo, cada componente trae consigo algunos problemas: + +- ¿Cómo solucionarás errores en el componente? +- ¿El componente te limita a hardware o sistemas de software específicos? +- ¿Qué harás si el componente falla completamente? + +Siempre es mejor encapsular el componente de alguna manera para que esté aislado y pueda ser reemplazado. Si resulta ser completamente infuncional, es posible que puedas obtener uno diferente, pero es posible que debas escribir el tuyo propio. La encapsulación no es portabilidad, pero facilita el proceso de portabilidad, lo cual es casi tan bueno. + +Tener el código fuente de un componente reduce el riesgo en un factor de cuatro. Con el código fuente, puedes evaluarlo fácilmente, depurarlo con mayor facilidad, encontrar soluciones alternativas más fácilmente y realizar correcciones más fácilmente. Si haces correcciones, debes proporcionarlas al propietario del componente y lograr que se incorporen a una versión oficial; de lo contrario, tendrás que mantener incómodamente una versión no oficial. + +Siguiente [¿Cómo decidir si el software es demasiado inmaduro?](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/es/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md b/es/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md new file mode 100644 index 0000000..d772457 --- /dev/null +++ b/es/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -0,0 +1,18 @@ +# ¿Cómo decidir si el software es demasiado inmaduro? +[//]: # (Version:1.0.0) +Usar software escrito por otras personas es una de las formas más efectivas de construir rápidamente un sistema sólido. No debería desalentarse, pero los riesgos asociados deben ser examinados. Uno de los mayores riesgos es el período de errores y casi inoperabilidad que a menudo está asociado con el software antes de que madure, a través del uso, en un producto utilizable. Antes de considerar la integración con un sistema de software, ya sea creado internamente o por un tercero, es muy importante considerar si realmente está lo suficientemente maduro como para ser utilizado. Aquí hay diez preguntas que deberías hacerte al respecto: + +1. ¿Es solo promesas? (Las promesas son muy inmaduras). +2. ¿Hay un cuerpo accesible de conocimientos sobre el software? +3. ¿Eres el primer usuario? +4. ¿Hay un fuerte incentivo para continuar? +5. ¿Ha tenido un esfuerzo de mantenimiento? +6. ¿Sobrevivirá a la defección de los actuales encargados del mantenimiento? +7. ¿Hay una alternativa experimentada al menos tan buena? +8. ¿Es conocido por tu tribu o empresa? +9. ¿Es deseable para tu tribu o empresa? +10. ¿Puedes contratar personas para trabajar en él incluso si es malo? + +Un poco de consideración de estos criterios demuestra el gran valor del software libre y del código abierto bien establecido para reducir el riesgo para el emprendedor. + +Siguiente [¿Cómo tomar una decisión de compra frente a desarrollo interno?](04-How-to-Make-a-Buy-vs-Build-Decision.md) \ No newline at end of file diff --git a/es/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md b/es/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md new file mode 100644 index 0000000..2d93060 --- /dev/null +++ b/es/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -0,0 +1,15 @@ +# ¿Cómo tomar una decisión de compra frente a desarrollo interno? +[//]: # (Version:1.0.0) +Una empresa o proyecto empresarial que intenta lograr algo con software tiene que tomar constantemente decisiones llamadas *comprar vs. construir*. Esta expresión es desafortunada por dos razones: parece ignorar el software de código abierto y gratuito que no es necesariamente *comprado*. Aún más importante, quizás debería llamarse una decisión de *obtener e integrar vs. construir aquí e integrar*, porque se debe considerar el costo de la integración. Esto requiere una gran combinación de perspicacia empresarial, de gestión e ingenieril. + +- ¿Qué tan bien se ajustan tus necesidades a aquellas para las que fue diseñado? +- ¿Qué parte de lo que compras necesitarás? +- ¿Cuál es el costo de evaluar la integración? +- ¿Cuál es el costo de la integración? +- ¿Comprar aumentará o disminuirá los costos de mantenimiento a largo plazo? +- ¿Construirlo te colocará en una posición comercial en la que no quieres estar? + +Deberías pensarlo dos veces antes de construir algo lo suficientemente grande como para servir como base para todo otro negocio. Tales ideas a menudo son propuestas por personas brillantes y optimistas que tendrán mucho que aportar a tu equipo. Si su idea es convincente, es posible que desees cambiar tu plan de negocios; pero no inviertas en una solución más grande que tu propio negocio sin pensarlo conscientemente. + +Después de considerar estas preguntas, deberías preparar dos planes de proyecto preliminares, uno para construir y otro para comprar. Esto te obligará a considerar los costos de integración. También debes considerar los costos de mantenimiento a largo plazo de ambas soluciones. Para estimar los costos de integración, tendrás que hacer una evaluación exhaustiva del software antes de comprarlo. Si no puedes evaluarlo, asumirás un riesgo irrazonable al comprar ese producto y deberías decidir no comprar ese producto en particular. Si hay varias decisiones de compra en consideración, se deberá dedicar algo de energía a evaluar cada una. +Siguiente [¿Cómo crecer profesionalmente?](05-How-to-Grow-Professionally.md) diff --git a/es/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md b/es/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md new file mode 100644 index 0000000..bea847c --- /dev/null +++ b/es/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -0,0 +1,11 @@ +# ¿Cómo crecer profesionalmente? +[//]: # (Version:1.0.0) +Asume responsabilidades por encima de tu autoridad. Desempeña el papel que deseas. Expresa agradecimiento por la contribución de las personas al éxito de la organización en general, así como por las cosas que te ayudan personalmente. + +Si quieres convertirte en líder de equipo, instiga la formación de consensos. Si quieres ser un gerente, asume la responsabilidad del cronograma. Normalmente, puedes hacer esto cómodamente mientras trabajas con un líder o gerente, ya que esto les libera para asumir una mayor responsabilidad. Si eso es demasiado, hazlo poco a poco. + +Evalúate a ti mismo. Si deseas convertirte en un mejor programador, pregúntale a alguien a quien admires cómo puedes llegar a ser como ellos. También puedes preguntarle a tu jefe, quien sabrá menos pero tendrá un mayor impacto en tu carrera. + +Planifica formas de aprender nuevas habilidades, tanto las técnicas triviales, como aprender un nuevo sistema de software, como las difíciles habilidades sociales, como escribir bien, integrándolas en tu trabajo. + +Siguiente [¿Cómo evaluar a los candidatos en una entrevista?](06-How-to-Evaluate-Interviewees.md) \ No newline at end of file diff --git a/es/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md b/es/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md new file mode 100644 index 0000000..e3fa3dc --- /dev/null +++ b/es/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -0,0 +1,15 @@ +# ¿Cómo evaluar a los candidatos en una entrevista? +[//]: # (Version:1.0.0) +Evaluar a posibles empleados no recibe la atención que merece. Una mala contratación, al igual que un mal matrimonio, es terrible. Una parte significativa de la energía de todos debería dedicarse al reclutamiento, aunque esto rara vez se hace. + +Existen diferentes estilos de entrevistas. Algunas son tortuosas, diseñadas para poner al candidato bajo una gran presión. Esto sirve para revelar posibles defectos de carácter y debilidades bajo estrés. Los candidatos no son más honestos con los entrevistadores de lo que son consigo mismos, y la capacidad humana para la autoengaño es asombrosa. + +Deberías, como mínimo, dar al candidato el equivalente a un examen oral sobre habilidades técnicas durante dos horas. Con práctica, podrás cubrir rápidamente lo que saben y retirarte rápidamente de lo que no saben para marcar los límites. Los entrevistados respetarán esto. Varias veces he escuchado a entrevistados decir que la calidad del examen fue una de sus motivaciones para elegir una empresa. Las personas talentosas quieren ser contratadas por sus habilidades, no por donde trabajaron anteriormente o a qué escuela asistieron, o alguna otra característica prescindible. + +Al hacer esto, también debes evaluar su capacidad para aprender, que es mucho más importante que lo que saben. También debes observar el olor a azufre que emiten las personas difíciles. Puedes reconocerlo comparando notas después de la entrevista, pero en el calor de la entrevista es difícil de reconocer. La forma en que las personas se comunican y trabajan con los demás es más importante que estar actualizado con el último lenguaje de programación. + +Un lector ha tenido buenos resultados utilizando un examen práctico para los entrevistados. Esto tiene la ventaja de que puede descubrir al entrevistado que puede presentarse bien pero que realmente no sabe programar, y hay muchas personas así. Personalmente, no he probado esta técnica, pero suena sensata. + +Finalmente, la entrevista también es un proceso de venta. Deberías estar vendiendo tu empresa o proyecto al candidato. Sin embargo, estás hablando con un programador, así que no trates de colorear la verdad. Comienza con lo malo y luego termina fuerte con lo bueno. + +Siguiente [¿Cómo saber cuándo aplicar conceptos avanzados de ciencias de la computación?](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/es/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md b/es/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md new file mode 100644 index 0000000..95f6e4f --- /dev/null +++ b/es/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -0,0 +1,15 @@ +# ¿Cómo saber cuándo aplicar conceptos avanzados de ciencias de la computación? +[//]: # (Version:1.0.0) +Hay un cuerpo de conocimiento sobre algoritmos, estructuras de datos, matemáticas y otras cosas sorprendentes que la mayoría de los programadores conocen pero rara vez utilizan. En la práctica, estas maravillas son demasiado complicadas y generalmente innecesarias. No tiene sentido mejorar un algoritmo cuando la mayor parte del tiempo se gasta haciendo llamadas ineficientes a la base de datos, por ejemplo. Una cantidad lamentable de programación consiste en hacer que los sistemas se comuniquen entre sí y usar estructuras de datos muy simples para construir una interfaz de usuario agradable. + +¿Cuándo es apropiada la tecnología de alta gama? ¿Cuándo debes consultar un libro para obtener algo más que un algoritmo corriente? A veces es útil hacerlo, pero debe evaluarse cuidadosamente. + +Las tres consideraciones más importantes para la técnica potencial de ciencias de la computación son: + +- ¿Está bien encapsulado para que el riesgo para otros sistemas sea bajo y el aumento general en complejidad y costo de mantenimiento sea bajo? +- ¿Es el beneficio sorprendente (por ejemplo, un factor de dos en un sistema maduro o un factor de diez en un sistema nuevo)? +- ¿Podrás probarlo y evaluarlo de manera efectiva? + +Si un algoritmo bien aislado que utiliza un algoritmo ligeramente avanzado puede disminuir el costo del hardware o aumentar el rendimiento en un factor de dos en todo un sistema, entonces sería criminal no considerarlo. Una de las claves para argumentar a favor de este enfoque es mostrar que el riesgo es realmente bastante bajo, ya que la tecnología propuesta probablemente ha sido bien estudiada; el único problema es el riesgo de integración. Aquí es donde la experiencia y el juicio de un programador pueden realmente potenciarse con la tecnología avanzada para facilitar la integración. + +Siguiente [¿Cómo hablar con personas no ingenieras?](08-How-to-Talk-to-Non-Engineers.md) \ No newline at end of file diff --git a/es/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md b/es/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md new file mode 100644 index 0000000..1b0ae88 --- /dev/null +++ b/es/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -0,0 +1,19 @@ +# ¿Cómo hablar con personas no ingenieras? +[//]: # (Version:1.0.0) +Los ingenieros y, en particular, los programadores, generalmente son reconocidos por la cultura popular como diferentes de otras personas. Esto implica que los demás son diferentes de nosotros. Esto es algo que vale la pena recordar al comunicarnos con no ingenieros; siempre debes entender a la audiencia. + +Los no ingenieros son inteligentes, pero no están tan centrados en crear cosas técnicas como nosotros. Nosotros creamos cosas. Ellos venden cosas y manejan cosas y cuentan cosas y gestionan cosas, pero no son expertos en hacer cosas. No son tan buenos para trabajar en equipos como los ingenieros (sin duda hay excepciones). Sus habilidades sociales generalmente son tan buenas o mejores que las de los ingenieros en entornos no de equipo, pero su trabajo no siempre exige que practiquen el tipo de comunicación íntima, precisa y cuidadosa que nosotros hacemos. + +Los no ingenieros pueden estar demasiado ansiosos por complacer y pueden intimidarse contigo. Al igual que nosotros, pueden decir "sí" sin realmente querer decirlo para complacerte o porque tienen un poco de miedo de ti y luego no cumplen con sus palabras. + +Los no programadores pueden entender cosas técnicas, pero no tienen esa cosa que es tan difícil incluso para nosotros: el juicio técnico. Entienden cómo funciona la tecnología, pero no pueden entender por qué un enfoque tomaría tres meses y otro tres días. (Después de todo, anecdóticamente, los programadores son horribles en este tipo de estimaciones también). Esto representa una gran oportunidad para sinergizar con ellos. + +Cuando hablas con tu equipo, usarás sin pensar un tipo de lenguaje abreviado, un lenguaje abreviado que es efectivo porque tendrás mucha experiencia compartida sobre tecnología en general y tu producto en particular. Se necesita un poco de esfuerzo para no usar este lenguaje abreviado con aquellos que no tienen esa experiencia compartida, especialmente cuando miembros de tu propio equipo están presentes. Este vocabulario crea una barrera entre tú y aquellos que no lo comparten y, lo que es peor, desperdicia su tiempo. + +Con tu equipo, las suposiciones y metas básicas no necesitan repetirse a menudo, y la mayor parte de la conversación se centra en los detalles. Con los externos, debe ser al revés. Es posible que no comprendan cosas que das por sentadas. Como las das por sentadas y no las repites, puedes salir de una conversación con un externo pensando que se entienden mutuamente cuando realmente hay un gran malentendido. Debes asumir que habrá una mala comunicación y observar cuidadosamente para encontrar este malentendido. Trata de hacer que resuman o parafraseen lo que estás diciendo para asegurarte de que comprendan. Si tienes la oportunidad de reunirte con ellos con frecuencia, dedica un poco de tiempo a preguntar si estás comunicándote eficazmente y cómo puedes hacerlo mejor. Si hay un problema de comunicación, busca cambiar tus propias prácticas antes de frustrarte con las suyas. + +Me encanta trabajar con no ingenieros. Ofrece grandes oportunidades para aprender y enseñar. A menudo puedes liderar con el ejemplo en términos de claridad de tu comunicación. Los ingenieros están entrenados para traer orden del caos, para aportar claridad a la confusión, y a los no ingenieros les gusta esto de nosotros. Como tenemos juicio técnico y generalmente podemos entender los problemas comerciales, a menudo podemos encontrar una solución simple a un problema. + +A menudo, los no ingenieros proponen soluciones que creen que nos facilitarán las cosas por amabilidad y el deseo de hacer lo correcto, cuando de hecho existe una solución general mucho mejor que solo puede verse al sinergizar la vista del externo con tu juicio técnico. Personalmente, me gusta Extreme Programming porque aborda esta ineficiencia; al vincular rápidamente la estimación con la idea, facilita encontrar la idea que es la mejor combinación de costo y beneficio. + +Siguiente [habilidades avanzadas](../../3-Advanced) diff --git a/es/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/es/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..25f6903 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,15 @@ +# ¿Cómo mantenerse motivado? +[//]: # (Version:1.0.0) +Es un hecho maravilloso y sorprendente que los programadores estén altamente motivados por el deseo de crear artefactos que sean hermosos, útiles o ingeniosos. Este deseo no es único de los programadores ni universal, pero es tan fuerte y común entre ellos que los separa de otros en diferentes roles. + +Esto tiene consecuencias prácticas e importantes. Si se le pide a los programadores que hagan algo que no sea hermoso, útil o ingenioso, su moral será baja. Hay mucho dinero que ganar haciendo cosas feas, estúpidas y aburridas; pero al final, la diversión generará más dinero para la empresa. + +Obviamente, existen industrias enteras organizadas alrededor de técnicas motivacionales, algunas de las cuales se aplican aquí. Las cosas específicas de la programación que puedo identificar son: + +- Utiliza el mejor lenguaje para el trabajo. +- Busca oportunidades para aplicar nuevas técnicas, lenguajes y tecnologías. +- Trata de aprender o enseñar algo, por pequeño que sea, en cada proyecto. + +Finalmente, si es posible, mide el impacto de tu trabajo en términos de algo que sea personalmente motivador. Por ejemplo, al corregir errores, contar la cantidad de errores que he corregido no es motivador para mí en absoluto, porque es independiente de la cantidad que aún puede existir, y también afecta el valor total que estoy agregando a los clientes de mi empresa solo de la manera más pequeña posible. Relacionar cada error con un cliente satisfecho, sin embargo, *sí* es personalmente motivador para mí. + +Siguiente [¿Cómo ser ampliamente confiado?](02-How-to-be-Widely-Trusted.md) diff --git a/es/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md b/es/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md new file mode 100644 index 0000000..1067bc1 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -0,0 +1,7 @@ +# ¿Cómo ser ampliamente confiado? +[//]: # (Version:1.0.0) +Para ser confiable, debes ser digno de confianza. También debes ser visible. Si nadie sabe de ti, no se depositará confianza en ti. Con aquellos cercanos a ti, como tus compañeros de equipo, esto no debería ser un problema. Estableces la confianza siendo receptivo e informativo con aquellos fuera de tu departamento o equipo. Ocasionalmente, alguien puede abusar de esta confianza y pedir favores irrazonables. No tengas miedo de esto, simplemente explica lo que tendrías que dejar de hacer para cumplir el favor. + +No finjas saber algo que no sabes. Con personas que no son compañeros de equipo, es posible que debas hacer una clara distinción entre 'no saber de inmediato' y 'no poder averiguarlo nunca'. + +Siguiente [¿Cómo hacer equilibrio entre tiempo y espacio?](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/es/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md b/es/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md new file mode 100644 index 0000000..3632513 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -0,0 +1,15 @@ +# ¿Cómo hacer equilibrio entre tiempo y espacio? +[//]: # (Version:1.0.0) +Puedes ser un buen programador sin ir a la universidad, pero no puedes ser un buen programador intermedio sin conocer la teoría básica de complejidad computacional. No es necesario que conozcas la notación 'big O', pero personalmente creo que deberías poder entender la diferencia entre 'tiempo constante', 'n log n' y 'n al cuadrado'. Puedes intuir cómo negociar el tiempo contra el espacio sin este conocimiento, pero en su ausencia no tendrás una base sólida para comunicarte con tus colegas. + +En el diseño o comprensión de un algoritmo, la cantidad de tiempo que tarda en ejecutarse a veces es una función del tamaño de la entrada. Cuando eso es cierto, podemos decir que el tiempo de ejecución del peor/caso esperado/mejor de un algoritmo es 'n log n' si es proporcional al tamaño ($n$) multiplicado por el logaritmo del tamaño. La notación y la forma de hablar también se pueden aplicar al espacio ocupado por una estructura de datos. + +Para mí, la teoría de complejidad computacional es tan hermosa y profunda como la física, ¡y un poco va un largo camino! + +El tiempo (ciclos del procesador) y el espacio (memoria) se pueden intercambiar entre sí. La ingeniería se trata de compromisos, y este es un buen ejemplo. No siempre es sistemático. En general, sin embargo, se puede ahorrar espacio codificando las cosas de manera más ajustada, a expensas de más tiempo de computación cuando tienes que decodificarlas. Puedes ahorrar tiempo almacenando en caché, es decir, gastando espacio para almacenar una copia local de algo, a expensas de tener que mantener la consistencia de la caché. A veces puedes ahorrar tiempo manteniendo más información en una estructura de datos. Esto generalmente cuesta una pequeña cantidad de espacio, pero puede complicar el algoritmo. + +Mejorar el intercambio de espacio/tiempo a menudo puede cambiar uno u otro dramáticamente. Sin embargo, antes de trabajar en esto, deberías preguntarte si lo que estás mejorando es realmente lo que necesita más mejoras. Es divertido trabajar en un algoritmo, pero no puedes dejar que eso te ciegue ante el hecho frío y duro de que mejorar algo que no es un problema no hará ninguna diferencia notable y creará una carga de pruebas. + +La memoria en las computadoras modernas parece barata, porque a diferencia del tiempo del procesador, no puedes ver que se esté utilizando hasta que te encuentras con el límite; pero luego el fallo es catastrófico. También hay otros costos ocultos al usar memoria, como tu efecto en otros programas que deben residir en ella y el tiempo para asignarla y desasignarla. Considera esto cuidadosamente antes de intercambiar espacio para ganar velocidad. + +Siguiente [¿Cómo realizar pruebas de resistencia?](04-How-to-Stress-Test.md) diff --git a/es/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md b/es/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md new file mode 100644 index 0000000..5f82330 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -0,0 +1,17 @@ +# ¿Cómo realizar pruebas de resistencia? +[//]: # (Version:1.0.0) +Las pruebas de estrés son divertidas. Al principio, parece que el propósito de las pruebas de estrés es descubrir si el sistema funciona bajo carga. En realidad, es común que el sistema funcione bajo carga pero falle de alguna manera cuando la carga es lo suficientemente pesada. Llamo a esto chocar *contra la pared* o *bonking*[1]. Puede haber algunas excepciones, pero casi siempre hay una ‘pared’. El propósito de las pruebas de estrés es descubrir dónde está la pared y luego averiguar cómo moverla más hacia afuera. + +Un plan para las pruebas de estrés debe desarrollarse temprano en el proyecto, porque a menudo ayuda a aclarar exactamente lo que se espera. ¿Dos segundos para una solicitud de página web son un fracaso miserable o un éxito rotundo? ¿Son suficientes 500 usuarios concurrentes? Eso, por supuesto, depende, pero uno debe saber la respuesta al diseñar el sistema que responde a la solicitud. La prueba de estrés necesita modelar la realidad lo suficientemente bien como para ser útil. No es realmente posible simular fácilmente a 500 humanos erráticos e impredecibles usando un sistema al mismo tiempo, pero al menos se pueden crear 500 simulaciones e intentar modelar alguna parte de lo que podrían hacer. + +En las pruebas de estrés, comienza con una carga ligera y carga el sistema a lo largo de alguna dimensión, como la tasa de entrada o el tamaño de la entrada, hasta que choques contra la pared. Si la pared está demasiado cerca para satisfacer tus necesidades, averigua cuál es el recurso limitante (generalmente hay uno dominante). ¿Es la memoria, el procesador, la E/S, el ancho de banda de la red o la contención de datos? Luego, descubre cómo puedes mover la pared. Ten en cuenta que mover la pared, es decir, aumentar la carga máxima que el sistema puede manejar, podría no ayudar o incluso perjudicar el rendimiento de un sistema ligeramente cargado. Por lo general, el rendimiento bajo carga pesada es más importante que el rendimiento bajo carga ligera. + +Es posible que debas obtener visibilidad en varias dimensiones diferentes para construir un modelo mental de ello; ninguna técnica única es suficiente. Por ejemplo, el registro a menudo da una buena idea del tiempo de reloj entre dos eventos en el sistema, pero a menos que esté cuidadosamente construido, no proporciona visibilidad en la utilización de la memoria ni siquiera en el tamaño de la estructura de datos. De manera similar, en un sistema moderno, varios equipos y muchos sistemas de software pueden estar cooperando. Especialmente cuando chocas contra la pared (es decir, el rendimiento no es lineal en el tamaño de la entrada), estos otros sistemas de software pueden ser un cuello de botella. La visibilidad en estos sistemas, incluso si solo mides la carga del procesador en todas las máquinas participantes, puede ser muy útil. + +Saber dónde está la pared es esencial no solo para moverla, sino también para proporcionar previsibilidad para que el negocio se pueda gestionar de manera efectiva. + +-- + +[1] "chocar" + +Siguiente [¿Cómo equilibrar brevedad y abstracción?](05-How-to-Balance-Brevity-and-Abstraction.md) \ No newline at end of file diff --git a/es/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md b/es/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md new file mode 100644 index 0000000..f2d5e15 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -0,0 +1,9 @@ +# ¿Cómo equilibrar brevedad y abstracción? +[//]: # (Version:1.0.0) +La abstracción es clave en la programación. Debes elegir cuidadosamente cuánta abstracción necesitas. Los programadores principiantes, en su entusiasmo, a menudo crean más abstracción de la realmente útil. Una señal de esto es si creas clases que realmente no contienen ningún código y no hacen nada más que servir para abstraer algo. La atracción de esto es comprensible, pero el valor de la brevedad del código debe medirse contra el valor de la abstracción. Ocasionalmente, uno ve un error cometido por idealistas entusiastas: al comienzo del proyecto se definen muchas clases que parecen maravillosamente abstractas y se puede especular que manejarán todas las eventualidades que puedan surgir. A medida que avanza el proyecto y se instala la fatiga, el código en sí mismo se vuelve desordenado. Los cuerpos de las funciones son más largos de lo que deberían ser. Las clases vacías son una carga para la documentación que se ignora cuando hay presión. El resultado final habría sido mejor si la energía gastada en la abstracción se hubiera gastado en mantener las cosas cortas y simples. Esto es una forma de programación especulativa. Recomiendo encarecidamente el artículo ['La concisión es poder' de Paul Graham.](http://www.paulgraham.com/power.html). + +Hay un cierto dogma asociado con técnicas útiles como *ocultamiento de información* y *programación orientada a objetos* que a veces se llevan demasiado lejos. Estas técnicas permiten codificar de manera abstracta y anticipar cambios. Personalmente, sin embargo, creo que no deberías producir mucho código especulativo. Por ejemplo, es un estilo aceptado ocultar una variable entera en un objeto detrás de mutadores y accesores, de modo que la variable misma no se expone, solo la pequeña interfaz a ella. Esto permite que la implementación de esa variable se cambie sin afectar el código de llamada y es quizás apropiado para un escritor de bibliotecas que debe publicar una API muy estable. Pero no creo que el beneficio de esto compense el costo de la prolijidad cuando mi equipo posee el código de llamada y, por lo tanto, puede recodificar el llamante tan fácilmente como al llamado. Cuatro o cinco líneas extra de código son un precio alto a pagar por este beneficio especulativo. + +La portabilidad plantea un problema similar. ¿Debería el código ser portátil a una computadora, compilador, sistema de software o plataforma diferente, o simplemente fácilmente portable? Creo que un código no portátil, corto y fácilmente portable es mejor que uno largo y portátil. Es relativamente fácil y ciertamente una buena idea confinar el código no portátil a áreas designadas, como una clase que realiza consultas a la base de datos específicas de un determinado sistema de gestión de bases de datos (DBMS). + +Siguiente [¿Cómo aprender nuevas habilidades?](06-How-to-Learn-New-Skills.md) diff --git a/es/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md b/es/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md new file mode 100644 index 0000000..ba5ae19 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -0,0 +1,13 @@ +# ¿Cómo aprender nuevas habilidades? +[//]: # (Version:1.0.0) +Aprender nuevas habilidades, especialmente las no técnicas, es la mayor diversión de todas. La mayoría de las empresas tendrían un mejor ambiente si comprendieran cuánto motiva a los programadores esto. + +Los humanos aprenden haciendo. Leer libros y asistir a clases es útil. Pero, ¿podrías tener respeto por un programador que nunca ha escrito un programa? Para aprender cualquier habilidad, debes ponerte en una posición tolerante donde puedas ejercitar esa habilidad. Al aprender un nuevo lenguaje de programación, trata de hacer un pequeño proyecto en él antes de tener que hacer uno grande. Al aprender a gestionar un proyecto de software, intenta gestionar uno pequeño primero. + +Un buen mentor no reemplaza hacer las cosas por ti mismo, pero es mucho mejor que un libro. ¿Qué puedes ofrecer a un mentor potencial a cambio de sus conocimientos? Como mínimo, deberías ofrecerte a estudiar arduamente para que su tiempo no sea desperdiciado. + +Intenta que tu jefe te permita recibir formación formal, pero comprende que a menudo no es mucho mejor que la misma cantidad de tiempo simplemente jugando con la nueva habilidad que quieres aprender. Sin embargo, es más fácil pedir capacitación que tiempo de juego en nuestro mundo imperfecto, aunque mucha formación formal consiste en dormir durante conferencias esperando la fiesta. + +Si lideras personas, comprende cómo aprenden y ayúdalos asignándoles proyectos del tamaño adecuado y que ejerciten habilidades en las que estén interesados. No olvides que las habilidades más importantes para un programador no son las técnicas. Da a tus colaboradores la oportunidad de jugar y practicar la valentía, honestidad y comunicación. + +Siguiente [Aprender a escribir](07-Learn-to-Type.md) diff --git a/es/2-Intermediate/Personal-Skills/07-Learn-to-Type.md b/es/2-Intermediate/Personal-Skills/07-Learn-to-Type.md new file mode 100644 index 0000000..3e5f611 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -0,0 +1,5 @@ +# Aprender a escribir +[//]: # (Version:1.0.0) +Aprende a escribir a máquina sin mirar el teclado (touch-type). Esta es una habilidad intermedia porque escribir código es tan difícil que la velocidad a la que puedes escribir es irrelevante y no puede marcar mucha diferencia en el tiempo que lleva escribir código, sin importar cuán bueno seas. Sin embargo, cuando eres un programador intermedio, probablemente pasarás mucho tiempo escribiendo en lenguaje natural para tus colegas y otros. Esto es una prueba divertida de tu compromiso; toma tiempo dedicado que no es muy divertido aprender algo así. Se cuenta la leyenda de que cuando Michael Tiemann estaba en MCC, la gente se paraba fuera de su puerta para escuchar el zumbido generado por sus pulsaciones de teclas, que eran tan rápidas que eran indistinguibles. + +Siguiente [¿Cómo hacer pruebas de integración?](08-How-to-Do-Integration-Testing.md) \ No newline at end of file diff --git a/es/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md b/es/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md new file mode 100644 index 0000000..0daaa95 --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -0,0 +1,7 @@ +# ¿Cómo hacer pruebas de integración? +[//]: # (Version:1.0.0) +La prueba de integración es la prueba de la integración de varios componentes que han sido probados unitariamente. La integración es costosa y se refleja en las pruebas. Debes incluir tiempo para esto en tus estimaciones y tu cronograma. + +Idealmente, deberías organizar un proyecto de manera que no haya una fase al final donde la integración deba tener lugar explícitamente. Es mucho mejor integrar gradualmente las cosas a medida que se completan a lo largo del proyecto. Si no se puede evitar, estima cuidadosamente. + +Siguiente [Idiomas de comunicación](09-Communication-Languages.md) \ No newline at end of file diff --git a/es/2-Intermediate/Personal-Skills/09-Communication-Languages.md b/es/2-Intermediate/Personal-Skills/09-Communication-Languages.md new file mode 100644 index 0000000..301826a --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -0,0 +1,11 @@ +# Idiomas de comunicación +[//]: # (Version:1.0.0) +Existen algunos lenguajes, es decir, sistemas sintácticos formalmente definidos, que no son *lenguajes de programación*, sino lenguajes de comunicación; están diseñados específicamente para facilitar la comunicación a través de la estandarización. En 2003, los más importantes de estos son UML, XML y SQL. Deberías tener cierta familiaridad con todos ellos para poder comunicarte bien y decidir cuándo usarlos. + +UML es un sistema formal rico para realizar dibujos que describen diseños. Su belleza radica en que es visual y formal al mismo tiempo, capaz de transmitir mucha información si tanto el autor como la audiencia conocen UML. Necesitas conocerlo porque a veces los diseños se comunican en él. Hay herramientas muy útiles para hacer dibujos UML que lucen muy profesionales. En muchos casos, UML es demasiado formal, y me encuentro usando un estilo más simple de *cuadros y flechas* para dibujos de diseño. Pero estoy bastante seguro de que UML es al menos tan beneficioso como estudiar latín. + +XML es un estándar para definir nuevos estándares. No es una solución para problemas de intercambio de datos, aunque a veces se presenta como tal. Más bien, es una automatización bienvenida de la parte más aburrida del intercambio de datos, es decir, estructurar la representación en una secuencia lineal y analizar de nuevo en una estructura. Proporciona algunas verificaciones agradables de tipo y corrección, aunque nuevamente solo una fracción de lo que es probable que necesites en la práctica. + +SQL es un lenguaje de consulta y manipulación de datos muy potente y completo que no es exactamente un lenguaje de programación. Tiene muchas variaciones, típicamente bastante dependientes del producto, que son menos importantes que el núcleo estandarizado. SQL es la *lingua franca* de las bases de datos relacionales. Puede que trabajes o no en un campo que se beneficie de la comprensión de las bases de datos relacionales, pero deberías tener un entendimiento básico de ellas y de la sintaxis y el significado de SQL. + +Siguiente [Herramientas pesadas](10-Heavy-Tools.md) diff --git a/es/2-Intermediate/Personal-Skills/10-Heavy-Tools.md b/es/2-Intermediate/Personal-Skills/10-Heavy-Tools.md new file mode 100644 index 0000000..f4caa0a --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -0,0 +1,14 @@ +# Herramientas pesadas + [//]: # (Version:1.0.0) +A medida que nuestra cultura tecnológica avanza, la tecnología del software pasa de ser inconcebible, a investigación, a nuevos productos, a productos estandarizados, a productos ampliamente disponibles e económicos. Estas herramientas robustas pueden manejar grandes cargas, pero pueden resultar intimidantes y requieren una gran inversión en comprensión. El programador intermedio debe saber cómo gestionarlas y cuándo deben ser utilizadas o consideradas. + +En mi opinión, en este momento, algunas de las mejores herramientas robustas son: + +- Bases de datos relacionales, +- Motores de búsqueda de texto completo, +- Bibliotecas matemáticas, +- OpenGL, +- Analizadores XML, y +- Hojas de cálculo. + +Siguiente [¿Cómo analizar datos?](11-How-to-analyze-data.md) diff --git a/es/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md b/es/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md new file mode 100644 index 0000000..ea0f45d --- /dev/null +++ b/es/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -0,0 +1,11 @@ +# ¿Cómo analizar datos? +[//]: # (Version:1.0.0) +El análisis de datos es un proceso en las primeras etapas del desarrollo de software, cuando examinas una actividad comercial y encuentras los requisitos para convertirla en una aplicación de software. Esta es una definición formal que puede llevarte a pensar que el análisis de datos es una acción que sería mejor dejar en manos de los analistas de sistemas, mientras que tú, el programador, deberías enfocarte en codificar lo que alguien más ha diseñado. Si seguimos estrictamente el paradigma de ingeniería de software, esto podría ser correcto. Los programadores experimentados se convierten en diseñadores y los diseñadores más agudos se convierten en analistas de negocios, teniendo así derecho a pensar en todos los requisitos de datos y darte una tarea bien definida para llevar a cabo. Sin embargo, esto no es del todo preciso, porque los datos son el valor central de cada actividad de programación. Sea lo que sea que hagas en tus programas, ya sea mover o modificar datos. El analista de negocios está analizando las necesidades en una escala más grande, y el diseñador de software está apretando aún más esa escala para que, cuando el problema llegue a tu escritorio, parezca que todo lo que necesitas hacer es aplicar algoritmos inteligentes y empezar a mover datos existentes. + +Pero no es así. + +No importa en qué etapa empieces a mirarlo, los datos son la principal preocupación de una aplicación bien diseñada. Si observas de cerca cómo un analista de negocios obtiene los requisitos de las solicitudes del cliente, te darás cuenta de que los datos desempeñan un papel fundamental. El analista crea los llamados Diagramas de Flujo de Datos, donde se identifican todas las fuentes de datos y se da forma al flujo de información. Una vez que se han definido claramente qué datos deben formar parte del sistema, el diseñador dará forma a las fuentes de datos en términos de relaciones de base de datos, protocolos de intercambio de datos y formatos de archivo, para que la tarea esté lista para ser entregada al programador. Sin embargo, el proceso no ha terminado, porque tú (el programador), incluso después de este exhaustivo proceso de refinamiento de datos, debes analizar los datos para realizar la tarea de la mejor manera posible. La línea de fondo de tu tarea es el mensaje central de Niklaus Wirth, el padre de varios lenguajes. "Algoritmos + Estructuras de Datos = Programas". Nunca hay un algoritmo que esté solo, haciendo algo por sí mismo. Se supone que cada algoritmo debe hacer algo al menos a un fragmento de datos. + +Por lo tanto, dado que los algoritmos no giran sus ruedas en el vacío, necesitas analizar tanto los datos que alguien más ha identificado para ti como los datos necesarios para escribir tu código. Un ejemplo trivial aclarará el asunto. Estás implementando un procedimiento de búsqueda para una biblioteca. Según tus especificaciones, el usuario puede seleccionar libros por una combinación de género, autor, título, editorial, año de impresión y número de páginas. El objetivo final de tu rutina es producir una declaración SQL válida para buscar en la base de datos del servidor. Según estos requisitos, tienes varias opciones: verificar cada control a su vez, usando una declaración "switch" o varias declaraciones "if"; hacer un array de controles de datos, verificando cada elemento para ver si está establecido; crear (o usar) un objeto de control abstracto del cual heredar todos tus controles específicos y conectarlos a un motor de eventos. Si tus requisitos incluyen también ajustar el rendimiento de la consulta, asegurándote de que los elementos se verifiquen en un orden específico, puedes considerar el uso de un árbol de componentes para construir tu declaración SQL. Como puedes ver, la elección del algoritmo depende de los datos que decidas usar o crear. Tales decisiones pueden marcar la diferencia entre un algoritmo eficiente y uno desastroso. Sin embargo, la eficiencia no es la única preocupación. Puedes usar una docena de variables nombradas en tu código y hacerlo tan eficiente como sea posible. Pero dicho código puede no ser fácilmente mantenible. Quizás elegir un contenedor adecuado para tus variables podría mantener la misma velocidad y, además, permitir que tus colegas comprendan mejor el código cuando lo vean el próximo año. Además, elegir una estructura de datos bien definida puede permitirles ampliar la funcionalidad de tu código sin tener que reescribirlo. A largo plazo, tus elecciones de datos determinan cuánto tiempo sobrevivirá tu código después de que hayas terminado con él. Permíteme darte otro ejemplo, solo un poco más de comida para el pensamiento. Supongamos que tu tarea es encontrar todas las palabras en un diccionario con más de tres anagramas, donde un anagrama debe ser otra palabra en el mismo diccionario. Si lo piensas como una tarea computacional, terminarás con un esfuerzo interminable, tratando de trabajar todas las combinaciones de cada palabra y luego comparándolas con las demás palabras en la lista. Sin embargo, si analizas los datos disponibles, te darás cuenta de que cada palabra puede estar representada por un registro que contiene la palabra en sí y una matriz ordenada de sus letras como ID. Armado con dicho conocimiento, encontrar anagramas significa simplemente ordenar la lista en función del campo adicional y recoger aquellos que comparten el mismo ID. El algoritmo de fuerza bruta puede llevar varios días en ejecutarse, mientras que el inteligente es solo cuestión de segundos. Recuerda este ejemplo la próxima vez que te enfrentes a un problema intratable. + +Siguiente [Habilidades de Equipo - ¿Cómo gestionar el tiempo de desarrollo?](../Team-Skills/01-How-to-Manage-Development-Time.md) \ No newline at end of file diff --git a/es/2-Intermediate/README.md b/es/2-Intermediate/README.md new file mode 100644 index 0000000..aa766b7 --- /dev/null +++ b/es/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. Intermedio +[//]: # (Version:1.0.0) +- Habilidades Personales + - [¿Cómo Mantenerse Motivado?](Personal-Skills/01-How-to-Stay-Motivated.md) + - [¿Cómo Ser Ampliamente Confiado?](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [¿Cómo Hacer Equilibrio Entre Tiempo y Espacio?](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [¿Cómo Realizar Pruebas de Resistencia?](Personal-Skills/04-How-to-Stress-Test.md) + - [¿Cómo Equilibrar Brevedad y Abstracción?](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [¿Cómo Aprender Nuevas Habilidades?](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Aprender a Escribir](Personal-Skills/07-Learn-to-Type.md) + - [¿Cómo Hacer Pruebas de Integración?](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Idiomas de Comunicación](Personal-Skills/09-Communication-Languages.md) + - [Herramientas Pesadas](Personal-Skills/10-Heavy-Tools.md) + - [¿Cómo analizar datos?](Personal-Skills/11-How-to-analyze-data.md) +- Habilidades de Equipo + - [¿Cómo Gestionar el Tiempo de Desarrollo?](Team-Skills/01-How-to-Manage-Development-Time.md) + - [¿Cómo Gestionar los Riesgos del Software de Terceros?](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [¿Cómo Gestionar a los Consultores?](Team-Skills/03-How-to-Manage-Consultants.md) + - [¿Cómo Comunicar la Cantidad Adecuada?](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [¿Cómo Disentir Honradamente y Salir Airosos?](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- Juicio + - [¿Cómo Equilibrar la Calidad contra el Tiempo de Desarrollo?](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [¿Cómo Gestionar la Dependencia del Sistema de Software?](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [¿Cómo Decidir si el Software es Demasiado Inmaduro?](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [¿Cómo Tomar una Decisión de Compra frente a Desarrollo Interno?](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [¿Cómo Crecer Profesionalmente?](Judgment/05-How-to-Grow-zProfessionally.md) + - [¿Cómo Evaluar a los Candidatos en una Entrevista?](Judgment/06-How-to-Evaluate-Interviewees.md) + - [¿Cómo Saber Cuándo Aplicar Conceptos Avanzados de Ciencias de la Computación?](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [¿Cómo Hablar con Personas No Ingenieras?](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/es/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md b/es/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md new file mode 100644 index 0000000..0e00b2b --- /dev/null +++ b/es/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -0,0 +1,11 @@ +# ¿Cómo gestionar el tiempo de desarrollo? +[//]: # (Version:1.0.0) +Para gestionar el tiempo de desarrollo, mantén un plan de proyecto conciso y actualizado. Un plan de proyecto es una estimación, un cronograma, un conjunto de hitos para marcar el progreso y una asignación del tiempo de tu equipo o el tuyo propio para cada tarea en la estimación. También debería incluir otras cosas que debes recordar hacer, como reunirte con el equipo de aseguramiento de calidad, preparar documentación o solicitar equipos. Si estás en un equipo, el plan de proyecto debería ser un acuerdo consensuado, tanto al principio como a medida que avanzas. + +El plan de proyecto existe para ayudar a tomar decisiones, no para mostrar cuán organizado estás. Si el plan de proyecto es demasiado largo o no está actualizado, será inútil para tomar decisiones. En realidad, estas decisiones se refieren a personas individuales. El plan y tu juicio te permiten decidir si debes trasladar tareas de una persona a otra. Los hitos marcan tu progreso. Si utilizas una herramienta de planificación de proyectos sofisticada, no te dejes seducir por crear un Gran Diseño Desde el Principio (BDUF, por sus siglas en inglés) para el proyecto, sino úsalo para mantener la concisión y la actualización. + +Si te saltas un hito, debes tomar medidas inmediatas, como informar a tu jefe que la finalización programada de ese proyecto se ha retrasado esa cantidad. La estimación y el cronograma nunca podrían haber sido perfectos desde el principio; esto crea la ilusión de que podrías recuperar los días que perdiste en la última parte del proyecto. Puede que sí. Pero es tan probable que hayas subestimado esa parte como que la hayas sobreestimado. Por lo tanto, la finalización programada del proyecto ya se ha retrasado, te guste o no. + +Asegúrate de que tu plan incluya tiempo para: reuniones internas del equipo, demostraciones, documentación, actividades periódicas programadas, pruebas de integración, trato con personas externas, enfermedades, vacaciones, mantenimiento de productos existentes y mantenimiento del entorno de desarrollo. El plan de proyecto puede servir como una forma de brindar a personas externas o a tu jefe una visión de lo que tú o tu equipo están haciendo. Por esta razón, debería ser corto y estar actualizado. + +Siguiente [¿Cómo gestionar los riesgos del software de terceros?](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/es/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md b/es/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md new file mode 100644 index 0000000..a244fa9 --- /dev/null +++ b/es/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -0,0 +1,11 @@ +# ¿Cómo gestionar los riesgos del software de terceros? +[//]: # (Version:1.0.0) +Un proyecto a menudo depende del software producido por organizaciones que no controla. Hay grandes riesgos asociados con el software de terceros que deben ser reconocidos por todos los involucrados. + +Nunca, bajo ninguna circunstancia, deposites esperanzas en *vapor*. El vapor es cualquier software supuestamente prometido pero que aún no está disponible. Esta es la manera más segura de ir a la quiebra. No es prudente ser simplemente escéptico ante la promesa de una empresa de software de lanzar un producto específico con una función específica en una fecha determinada; es mucho más sabio ignorarlo por completo y olvidar que alguna vez lo escuchaste. Nunca dejes que se escriba en documentos utilizados por tu empresa. + +Si el software de terceros no es vapor, aún así conlleva riesgos, pero al menos es un riesgo que se puede abordar. Si estás considerando usar software de terceros, debes dedicar energía desde el principio a evaluarlo. A la gente puede que no le guste escuchar que llevará dos semanas o dos meses evaluar cada uno de los tres productos en cuanto a su idoneidad, pero se debe hacer tan pronto como sea posible. El costo de la integración no se puede estimar con precisión sin una evaluación adecuada. + +Entender la idoneidad del software de terceros existente para un propósito específico es un conocimiento muy tribal. Es muy subjetivo y generalmente reside en expertos. Puedes ahorrar mucho tiempo si puedes encontrar a esos expertos. Muchas veces, un proyecto dependerá tan completamente de un sistema de software de terceros que si falla la integración, el proyecto también fallará. Expresa claramente riesgos como ese por escrito en el cronograma. Intenta tener un plan de contingencia, como otro sistema que se pueda utilizar o la capacidad de escribir la funcionalidad tú mismo si el riesgo no se puede eliminar temprano. Nunca hagas que un cronograma dependa del vapor. + +Siguiente [¿Cómo gestionar a los consultores?](03-How-to-Manage-Consultants.md) \ No newline at end of file diff --git a/es/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/es/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..6b15655 --- /dev/null +++ b/es/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,9 @@ +# ¿Cómo gestionar a los consultores? +[//]: # (Version:1.0.0) +Usa consultores, pero no dependas de ellos. Son personas maravillosas y merecen mucho respeto. Dado que tienen la oportunidad de ver muchos proyectos diferentes, a menudo saben más sobre tecnologías específicas e incluso técnicas de programación que tú. La mejor manera de utilizarlos es como educadores internos que pueden enseñar mediante el ejemplo. + +Sin embargo, por lo general, no pueden formar parte del equipo de la misma manera que los empleados regulares, si solo porque es posible que no tengas suficiente tiempo para conocer sus fortalezas y debilidades. Su compromiso financiero es mucho menor. Pueden moverse con más facilidad. Es posible que tengan menos que ganar si a la empresa le va bien. Algunos serán buenos, algunos serán promedio y algunos serán malos, pero con suerte, la selección de consultores no será tan cuidadosa como la selección de empleados, así que obtendrás más malos. + +Si los consultores van a escribir código, debes revisarlo cuidadosamente a medida que avanzas. No puedes llegar al final de un proyecto con el riesgo de tener un gran bloque de código que no ha sido revisado. Esto es cierto para todos los miembros del equipo, realmente, pero generalmente tendrás más conocimiento de los miembros del equipo más cercanos a ti. + +Siguiente [¿Cómo comunicar la cantidad adecuada?](04-How-to-Communicate-the-Right-Amount.md) \ No newline at end of file diff --git a/es/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md b/es/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md new file mode 100644 index 0000000..65690bc --- /dev/null +++ b/es/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -0,0 +1,7 @@ +# ¿Cómo comunicar la cantidad adecuada? +[//]: # (Version:1.0.0) +Considera cuidadosamente el costo de una reunión; cuesta *su duración multiplicada por el número de participantes*. Las reuniones son a veces necesarias, pero por lo general, menos personas son mejores. La calidad de la comunicación en reuniones pequeñas es mejor, y se desperdicia menos tiempo en general. Si alguien se aburre en una reunión, tómalo como una señal de que la reunión debería ser más pequeña. + +Debería hacerse todo lo posible para fomentar la comunicación informal. Se realiza más trabajo útil durante los almuerzos con colegas que en cualquier otro momento. Es una lástima que más empresas no reconozcan ni respalden este hecho. + +Siguiente [¿Cómo disentir honradamente y salir airosos?](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/es/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md b/es/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md new file mode 100644 index 0000000..7ef7b32 --- /dev/null +++ b/es/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -0,0 +1,11 @@ +# ¿Cómo disentir honradamente y salir airosos? +[//]: # (Version:1.0.0) +La discrepancia es una gran oportunidad para tomar una buena decisión, pero debe manejarse delicadamente. Con suerte, sientes que has expresado adecuadamente tus pensamientos y que te han escuchado antes de que se tome la decisión. En ese caso, no hay nada más que decir, y debes decidir si respaldarás la decisión aunque estés en desacuerdo. Si puedes respaldar esta decisión a pesar de tu desacuerdo, dilo. Esto demuestra cuán valioso eres porque eres independiente y no eres un sí-hombre, pero eres respetuoso con la decisión y un jugador de equipo. + +A veces, se tomará una decisión con la que no estás de acuerdo cuando los tomadores de decisiones no tuvieron el beneficio completo de tu opinión. Debes evaluar si plantear el problema en función del beneficio para la empresa o la tribu. Si es un pequeño error en tu opinión, puede que no valga la pena reconsiderarlo. Si es un gran error en tu opinión, entonces, por supuesto, debes presentar un argumento. + +Por lo general, esto no es un problema. En algunas circunstancias estresantes y con algunos tipos de personalidad, esto puede llevar a que las cosas se tomen de manera personal. Por ejemplo, algunos programadores muy buenos carecen de la confianza necesaria para cuestionar una decisión incluso cuando tienen buenas razones para creer que está equivocada. En las peores circunstancias, el tomador de decisiones es inseguro y lo toma como un desafío personal a su autoridad. Lo mejor es recordar que en tales circunstancias, las personas reaccionan con la parte reptiliana de sus cerebros. Debes presentar tu argumento en privado e intentar mostrar cómo el nuevo conocimiento cambia la base sobre la cual se tomó la decisión. + +Ya sea que la decisión se revierta o no, debes recordar que nunca podrás decir '¡Te lo dije!' ya que la decisión alternativa fue completamente explorada. + +Siguiente [Juicio - ¿Cómo equilibrar la calidad contra el tiempo de desarrollo?](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/es/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md b/es/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md new file mode 100644 index 0000000..b6de927 --- /dev/null +++ b/es/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -0,0 +1,11 @@ +# ¿Cómo Combatir la Presión del Cronograma? +[//]: # (Version:1.0.0) +La presión del "time-to-market" es la presión por entregar un buen producto rápidamente. Es positiva porque refleja una realidad financiera y es saludable hasta cierto punto. La presión del cronograma es la presión por entregar algo más rápido de lo que se puede hacer, y es derrochadora, perjudicial y demasiado común. + +La presión del cronograma existe por varias razones. Las personas que asignan tareas a los programadores no aprecian completamente la ética laboral sólida que tenemos y lo divertido que es ser un programador. Tal vez porque proyectan su propio comportamiento en nosotros, creen que pedirlo antes hará que trabajemos más para entregarlo más rápido. Esto probablemente sea cierto, pero el efecto es muy pequeño y el daño es muy grande. Además, no tienen visibilidad sobre lo que realmente implica producir software. Al no poder verlo y no poder crearlo ellos mismos, lo único que pueden hacer es ver la presión del "time-to-market" y molestar a los programadores al respecto. + +La clave para combatir la presión del cronograma es simplemente convertirla en presión del "time-to-market". La forma de hacer esto es brindar visibilidad sobre la relación entre la mano de obra disponible y el producto. Producir una estimación honesta, detallada y, sobre todo, comprensible de todo el trabajo involucrado es la mejor manera de lograrlo. Tiene la ventaja adicional de permitir tomar decisiones de gestión acertadas sobre posibles compensaciones de funcionalidad. + +La idea clave que la estimación debe dejar clara es que la mano de obra es un fluido casi incompresible. No se puede empacar más en un período de tiempo, al igual que no se puede empacar más agua en un recipiente más allá del volumen de ese recipiente. En cierto sentido, un programador nunca debería decir "no", sino más bien decir "¿Qué estás dispuesto a renunciar para obtener eso que quieres?". El efecto de producir estimaciones claras será aumentar el respeto por los programadores. Así es como se comportan otros profesionales. El arduo trabajo de los programadores será visible. Establecer un cronograma poco realista también será dolorosamente obvio para todos. Los programadores no pueden ser engañados. Es irrespetuoso y desmoralizante pedirles que hagan algo irrealista. La Programación Extrema amplifica esto y construye un proceso en torno a ello; espero que cada lector tenga la suerte de usarlo. + +Siguiente [¿Cómo Entender al Usuario?](02-How-to-Understand-the-User.md) \ No newline at end of file diff --git a/es/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md b/es/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md new file mode 100644 index 0000000..00c31ba --- /dev/null +++ b/es/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -0,0 +1,17 @@ +# ¿Cómo Entender al Usuario? +[//]: # (Version:1.0.0) +Es tu deber entender al usuario y ayudar a tu jefe a comprender al usuario. Debido a que el usuario no está tan íntimamente involucrado en la creación de tu producto como tú, se comportan de manera un poco diferente: + +- El usuario generalmente hace afirmaciones cortas. +- El usuario tiene su propio trabajo; principalmente pensarán en pequeñas mejoras en tu producto, no en grandes mejoras. +- El usuario no puede tener una visión que represente a todos los usuarios de tu producto. + +Es tu deber darles lo que realmente quieren, no lo que dicen que quieren. Sin embargo, es mejor proponérselo y lograr que estén de acuerdo en que tu propuesta es lo que realmente quieren antes de comenzar, pero pueden no tener la visión para hacerlo. Tu confianza en tus propias ideas al respecto debería variar. Debes cuidarte tanto de la arrogancia como de la falsa modestia en cuanto a saber lo que el cliente realmente desea. Los programadores están entrenados para diseñar y crear. Los investigadores de mercado están entrenados para averiguar lo que la gente quiere. Estos dos tipos de personas, o dos modos de pensamiento en la misma persona, trabajando armoniosamente juntos, ofrecen la mejor oportunidad de formular la visión correcta. + +Cuanto más tiempo pases con los usuarios, mejor podrás entender qué será realmente exitoso. Deberías intentar probar tus ideas con ellos tanto como puedas. Deberías comer y beber con ellos si puedes. + +Guy Kawasaki [Rules] ha enfatizado la importancia de *observar* lo que hacen tus usuarios además de escucharlos. + +Creo que los contratistas y consultores a menudo tienen problemas tremendos para que sus clientes aclaren en sus mentes lo que realmente quieren. Si tienes la intención de ser consultor, te sugiero que elijas a tus clientes en función de su claridad mental, así como de sus billeteras. + +Siguiente [¿Cómo Obtener un Ascenso?](03-How-to-Get-a-Promotion.md) \ No newline at end of file diff --git a/es/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md b/es/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md new file mode 100644 index 0000000..3d31814 --- /dev/null +++ b/es/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -0,0 +1,13 @@ +# ¿Cómo Obtener un Ascenso? +[//]: # (Version:1.0.0) +Para ser ascendido a un puesto, actúa como si ya ocuparas ese puesto. + +Para ser promovido a un cargo, descubre qué se espera de ese cargo y hazlo. + +Para obtener un aumento salarial, negocia armado con información. + +Si sientes que ya es hora de recibir un ascenso, habla con tu jefe al respecto. Pregúntale explícitamente qué necesitas hacer para ser ascendido e intenta hacerlo. Esto puede sonar trivial, pero a menudo tu percepción de lo que necesitas hacer diferirá considerablemente de la de tu jefe. Además, esto comprometerá a tu jefe de cierta manera. + +La mayoría de los programadores probablemente tienen una percepción exagerada de sus habilidades relativas en algunos aspectos, ¡después de todo, no todos podemos estar en el top 10%! Sin embargo, he visto a algunas personas que eran seriamente subestimadas. No se puede esperar que la evaluación de todos coincida perfectamente con la realidad en todo momento, pero creo que las personas son generalmente moderadamente justas, con una advertencia: no puedes ser apreciado sin visibilidad en tu trabajo. A veces, debido a circunstancias fortuitas o hábitos personales, alguien puede pasar desapercibido. Trabajar mucho desde casa o estar geográficamente separado de tu equipo y jefe hace que esto sea especialmente difícil. + +Siguiente [Sirviendo a tu Equipo - ¿Cómo Desarrollar el Talento?](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/es/3-Advanced/README.md b/es/3-Advanced/README.md new file mode 100644 index 0000000..dcd81fc --- /dev/null +++ b/es/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. Avanzado +[//]: # (Version:1.0.0) +- Juicio Tecnológico + - [¿Cómo Distinguir lo Difícil de lo Imposible?](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [¿Cómo Utilizar Lenguajes Incorporados?](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Elección de Lenguajes](Technical-Judgment/03-Choosing-Languages.md) +- Comprometerse Sabiamente + - [¿Cómo Combatir la Presión del Cronograma?](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [¿Cómo Entender al Usuario?](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [¿Cómo Obtener un Ascenso?](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- Sirviendo a tu Equipo + - [¿Cómo Desarrollar el Talento?](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [¿Cómo Elegir en Qué Trabajar?](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [¿Cómo Obtener lo Mejor de tus Compañeros de Equipo?](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [¿Cómo Dividir Problemas?](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [¿Cómo Manejar Tareas Aburridas?](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [¿Cómo Obtener Apoyo para un Proyecto?](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [¿Cómo Hacer Crecer un Sistema?](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [¿Cómo Comunicarse Bien?](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [¿Cómo Decir Cosas que la Gente no Quiere Escuchar?](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [¿Cómo Lidiar con Mitos Gerenciales?](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [¿Cómo Lidiar con el Caos Organizacional?](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/es/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md b/es/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md new file mode 100644 index 0000000..bab85ed --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -0,0 +1,23 @@ +# ¿Cómo Desarrollar el Talento? +[//]: # (Version:1.0.1) +Nietzsche exageró cuando dijo [Stronger]: + +> Lo que no me destruye, me hace más fuerte. + +Tu mayor responsabilidad es con tu equipo. Debes conocer bien a cada uno de ellos. Debes desafiar a tu equipo, pero no sobrecargarlos. Por lo general, debes hablar con ellos sobre la forma en que están siendo desafiados. Si aceptan el desafío, estarán bien motivados. En cada proyecto, o cada dos proyectos, intenta desafiarlos tanto de la manera que sugieren como de la manera que crees que será buena para ellos. No los desafíes dándoles más trabajo, sino dándoles una nueva habilidad o, mejor aún, un nuevo rol en el equipo. + +Debes permitir que las personas (incluyéndote a ti mismo) fallen ocasionalmente y debes planificar cierto margen de error en tu cronograma. Si nunca hay fallos, no puede haber un sentido de aventura. Si no hay fallas ocasionales, no estás esforzándote lo suficiente. Cuando alguien falla, debes ser lo más comprensivo posible con ellos, sin tratarlos como si hubieran tenido éxito. + +Intenta que cada miembro del equipo participe y esté bien motivado. Pregúntales explícitamente a cada uno de ellos qué necesitan para estar bien motivados si no lo están. Es posible que tengas que dejarlos insatisfechos, pero debes conocer los deseos de todos. + +No puedes rendirte con alguien que intencionalmente no está cumpliendo con su parte de la carga debido a baja moral o insatisfacción y simplemente dejar que hagan el mínimo esfuerzo. Debes intentar motivarlos y hacerlos productivos. Mientras tengas paciencia, sigue haciéndolo. Cuando se agote tu paciencia, despídelos. No puedes permitir que alguien que trabaja intencionalmente por debajo de su nivel permanezca en el equipo, ya que no es justo para el equipo. + +Hazles saber a los miembros fuertes de tu equipo que crees que son fuertes diciéndolo en público. Los elogios deben ser públicos y las críticas privadas. + +Los miembros fuertes del equipo naturalmente tendrán tareas más difíciles que los miembros débiles del equipo. Esto es perfectamente natural y a nadie le molestará siempre y cuando todos trabajen arduamente. + +Es un hecho extraño que no se refleja en los salarios que un buen programador es más productivo que 10 malos programadores. Esto crea una situación extraña. A menudo será cierto que podrías avanzar más rápido si tus programadores débiles simplemente se apartaran. De hecho, harías más progresos a corto plazo. Sin embargo, tu tribu perdería algunos beneficios importantes, como la capacitación de los miembros más débiles, la difusión del conocimiento tribal y la capacidad de recuperarse de la pérdida de los miembros fuertes. Los fuertes deben ser comprensivos en este sentido y considerar el problema desde todos los ángulos. + +A menudo puedes asignar tareas desafiantes pero cuidadosamente delimitadas a los miembros más fuertes del equipo. + +Siguiente [¿Cómo Elegir en Qué Trabajar?](02-How-to-Choose-What-to-Work-On.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md b/es/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md new file mode 100644 index 0000000..3cc75ff --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -0,0 +1,5 @@ +# ¿Cómo Elegir en Qué Trabajar? +[//]: # (Version:1.0.1) +Equilibras tus necesidades personales con las necesidades del equipo al elegir en qué aspecto de un proyecto trabajar. Debes hacer lo que haces mejor, pero intenta encontrar una forma de desafiarte a ti mismo no asumiendo más trabajo, sino desarrollando una nueva habilidad. Las habilidades de liderazgo y comunicación son más importantes que las habilidades técnicas. Si eres muy competente, asume la tarea más difícil o arriesgada y hazlo lo antes posible en el proyecto para disminuir el riesgo. + +Siguiente [¿Cómo Obtener lo Mejor de tus Compañeros de Equipo?](03-How-to-Get-the-Most-From-Your-Teammates.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md b/es/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md new file mode 100644 index 0000000..2e0593a --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -0,0 +1,15 @@ +# ¿Cómo Obtener lo Mejor de tus Compañeros de Equipo? +[//]: # (Version:1.0.1) +Para obtener lo mejor de tus compañeros de equipo, desarrolla un buen espíritu de equipo y procura mantener a cada individuo tanto personalmente desafiado como comprometido. + +Para desarrollar el espíritu de equipo, cosas cursis como ropa con logotipos y fiestas son buenas, pero no tan buenas como el respeto personal. Si todos se respetan mutuamente, nadie querrá decepcionar a nadie. El espíritu de equipo se crea cuando las personas hacen sacrificios por el equipo y piensan en términos del bien del equipo antes que en su propio bien personal. Como líder, no puedes pedir más de lo que das tú mismo en este aspecto. + +Una de las claves para el liderazgo de equipo es facilitar el consenso para que todos estén comprometidos. Esto ocasionalmente significa permitir que tus compañeros de equipo se equivoquen. Es decir, si no perjudica demasiado al proyecto, debes permitir que algunos de tus compañeros hagan las cosas a su manera, basándose en el consenso, incluso si crees con gran confianza que es lo incorrecto. Cuando esto sucede, no estés de acuerdo, simplemente discrepa abiertamente y acepta el consenso. No suenes herido ni como si te estuvieran obligando, simplemente expresa que estás en desacuerdo pero que crees que el consenso del equipo es más importante. Esto a menudo los hará retroceder. No insistas en que continúen con su plan inicial si retroceden. + +Si hay una persona que no consiente después de haber discutido los problemas desde todos los lados apropiados, simplemente afirma que tienes que tomar una decisión y eso es lo que decides. Si hay una manera de juzgar si tu decisión será incorrecta o si más tarde se demuestra que es incorrecta, cambia tan rápido como puedas y reconoce a las personas que tenían razón. + +Pregunta a tu equipo, tanto como grupo como individualmente, qué piensan que crearía espíritu de equipo y haría que el equipo fuera efectivo. + +Elogia con frecuencia en lugar de hacerlo de manera extravagante. Elogia especialmente a aquellos que no están de acuerdo contigo cuando son dignos de elogio. Elogia en público y critica en privado; con una excepción: a veces, el crecimiento o la corrección de un defecto no se puede elogiar sin llamar la atención de manera embarazosa sobre el defecto original, así que el crecimiento debe elogiarse en privado. + +Siguiente [¿Cómo Dividir Problemas?](04-How-to-Divide-Problems-Up.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md b/es/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md new file mode 100644 index 0000000..6118c82 --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -0,0 +1,9 @@ +# ¿Cómo Dividir Problemas? +[//]: # (Version:1.0.1) +Es divertido tomar un proyecto de software y dividirlo en tareas que serán realizadas por individuos. Esto debería hacerse temprano. A veces, a los gerentes les gusta pensar que se puede hacer una estimación sin tener en cuenta a las personas que realizarán el trabajo. Esto es imposible, ya que la productividad de las personas varía considerablemente. Quién tiene conocimientos particulares sobre un componente también cambia constantemente y puede tener un efecto de magnitud en el rendimiento. + +Así como un compositor considera el timbre del instrumento que tocará una parte o un entrenador de un equipo deportivo considera las fortalezas de cada jugador, el líder de equipo experimentado generalmente no podrá separar la división del proyecto en tareas de los miembros del equipo a los que se les asignarán. Esta es parte de la razón por la cual un equipo de alto rendimiento no debería ser desmantelado. + +Hay un cierto peligro en esto, dado que las personas pueden aburrirse al construir sobre sus fortalezas y nunca mejorar sus debilidades o aprender nuevas habilidades. Sin embargo, la especialización es una herramienta de productividad muy útil cuando no se usa en exceso. + +Siguiente [¿Cómo Manejar Tareas Aburridas?](05-How-to-Handle-Boring-Tasks.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md b/es/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md new file mode 100644 index 0000000..27be52f --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -0,0 +1,7 @@ +# ¿Cómo Manejar Tareas Aburridas? +[//]: # (Version:1.0.1) +A veces no es posible evitar tareas aburridas que son críticas para el éxito de la empresa o el proyecto. Estas tareas realmente pueden afectar el ánimo de quienes tienen que realizarlas. La mejor técnica para lidiar con esto es invocar o promover la virtud de la pereza del programador según Larry Wall. Trata de encontrar alguna manera de hacer que la computadora realice la tarea por ti o ayudar a tus compañeros de equipo a hacerlo. Trabajar durante una semana en un programa para realizar una tarea que llevaría una semana hacer manualmente tiene la gran ventaja de ser más educativo y a veces más repetible. + +Si todo lo demás falla, discúlpate con aquellos que tienen que realizar la tarea aburrida, pero bajo ninguna circunstancia permitas que lo hagan solos. Como mínimo, asigna un equipo de dos personas para realizar el trabajo y fomenta un trabajo en equipo saludable para completar la tarea. + +Siguiente [¿Cómo Obtener Apoyo para un Proyecto?](06-How-to-Gather-Support-for-a-Project.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md b/es/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md new file mode 100644 index 0000000..b62022c --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -0,0 +1,5 @@ +# ¿Cómo Obtener Apoyo para un Proyecto? +[//]: # (Version:1.0.1) +Para obtener apoyo para un proyecto, crea y comunica una visión que demuestre un valor real para toda la organización. Intenta permitir que otros participen en la creación de tu visión. Esto les brinda una razón para apoyarte y te beneficia con sus ideas. Recluta individualmente a partidarios clave para tu proyecto. Siempre que sea posible, muestra en lugar de decir. Si es posible, construye un prototipo o un modelo para demostrar tus ideas. Un prototipo siempre es poderoso, pero en software es mucho más efectivo que cualquier descripción escrita. + +Siguiente [¿Cómo Hacer Crecer un Sistema?](07-How-to-Grow-a-System.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md b/es/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md new file mode 100644 index 0000000..231771d --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -0,0 +1,21 @@ +# ¿Cómo Hacer Crecer un Sistema? +[//]: # (Version:1.0.1) +La semilla de un árbol contiene la idea del adulto pero no realiza completamente la forma y potencia del adulto. El embrión crece. Se vuelve más grande. Se parece más al adulto y tiene más usos. Eventualmente da fruto. Más tarde, muere y su cuerpo alimenta a otros organismos. + +Tenemos el lujo de tratar el software de esa manera. Un puente no es así; nunca hay un puente bebé, sino simplemente un puente sin terminar. Los puentes son mucho más simples que el software. + +Es bueno pensar en el software como algo que crece, porque nos permite hacer un progreso útil antes de tener una imagen mental perfecta. Podemos obtener retroalimentación de los usuarios y usarla para corregir el crecimiento. Podar las ramas débiles es saludable. + +El programador debe diseñar un sistema terminado que se pueda entregar y usar. Pero el programador avanzado debe hacer más. Debes diseñar un camino de crecimiento que termine en el sistema terminado. Es tu trabajo tomar un germen de una idea y construir un camino que lo lleve de la manera más suave posible a un artefacto útil. + +Para hacer esto, debes visualizar el resultado final y comunicarlo de una manera que el equipo de ingeniería pueda emocionarse. Pero también debes comunicarles un camino que vaya desde donde están ahora hasta donde quieren estar sin grandes saltos. El árbol debe permanecer vivo todo el tiempo; no puede estar muerto en un momento y resucitar más tarde. + +Este enfoque se captura en el desarrollo en espiral. Se utilizan hitos que nunca están demasiado lejos para marcar el progreso a lo largo del camino. En el entorno ultra competitivo de los negocios, es mejor si los hitos se pueden lanzar y ganar dinero lo antes posible, incluso si están lejos de un punto final bien diseñado. Uno de los trabajos del programador es equilibrar la recompensa inmediata contra la recompensa futura eligiendo sabiamente un camino de crecimiento expresado en hitos. + +El programador avanzado tiene la triple responsabilidad de hacer crecer el software, los equipos y las personas. + +> Creo que subestimas la importancia aquí. No se trata solo de sistemas, sino también de algoritmos, interfaces de usuario, modelos de datos, y así sucesivamente. Es absolutamente *vital* tener un progreso medible hacia objetivos intermedios mientras trabajas en un sistema grande. Nada es tan malo como el horror especial de llegar al final y descubrir que todo simplemente no va a funcionar (mira el reciente desastre del Sistema de Noticias para Votantes). Incluso iría más allá y lo declararía como una ley de la naturaleza: ningún sistema grande y complejo puede implementarse desde cero, solo puede evolucionar de un sistema simple a un sistema complejo en una serie de pasos intencionales. + +A lo cual solo se puede responder *Fiat lux* (hágase la luz). + +Siguiente [¿Cómo Comunicarse Bien?](08-How-to-Communicate-Well.md) diff --git a/es/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md b/es/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md new file mode 100644 index 0000000..32cad7e --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -0,0 +1,11 @@ +# ¿Cómo Comunicarse Bien? +[//]: # (Version:1.0.1) +Para comunicarse bien, debes reconocer lo difícil que es. Es una habilidad por sí misma. Se complica por el hecho de que las personas con las que tienes que comunicarte son imperfectas. No se esfuerzan mucho en comprenderte. Hablan y escriben mal. A menudo están sobrecargados de trabajo o aburridos, y, como mínimo, están algo enfocados en su propio trabajo en lugar de los problemas más amplios que puedas estar abordando. Una de las ventajas de tomar clases y practicar la escritura, la oratoria y la escucha es que, si te vuelves hábil en ello, puedes ver más fácilmente dónde están los problemas y cómo corregirlos. + +El programador es un animal social cuya supervivencia depende de la comunicación con su equipo. El programador avanzado es un animal social cuya satisfacción depende de la comunicación con personas fuera de su equipo. + +El programador aporta orden al caos. Una forma interesante de hacerlo es iniciar una propuesta de algún tipo fuera del equipo. Esto se puede hacer en formato de *propuesta inicial* o *documento técnico* o simplemente verbalmente. Este liderazgo tiene la tremenda ventaja de establecer los términos del debate. También te expone a la crítica y, lo que es peor, al rechazo y al olvido. El programador avanzado debe estar preparado para aceptar esto, porque tiene un poder único y, por lo tanto, una responsabilidad única. Los emprendedores que no son programadores necesitan programadores para proporcionar liderazgo de alguna manera. Los programadores son la parte del puente entre las ideas y la realidad que descansa sobre la realidad. + +No he dominado la comunicación efectiva, pero lo que estoy intentando actualmente es lo que llamo un enfoque de cuatro puntas: después de tener mis ideas en orden y estar completamente preparado, intento hablar verbalmente, entregarles un documento técnico (en papel real, así como electrónicamente), mostrarles una demostración y luego repetir pacientemente este proceso. Creo que muchas veces no somos lo suficientemente pacientes en este tipo de comunicación difícil. No debes desanimarte si tus ideas no son aceptadas de inmediato. Si has invertido energía en su preparación, nadie pensará mal de ti por ello. + +Siguiente [¿Cómo Decir Cosas que la Gente no Quiere Escuchar?](09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) diff --git a/es/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md b/es/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md new file mode 100644 index 0000000..2b1564e --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -0,0 +1,9 @@ +# ¿Cómo Decir Cosas que la Gente no Quiere Escuchar? +[//]: # (Version:1.0.1) +A menudo tendrás que decirles a las personas cosas que las harán sentir incómodas. Recuerda que estás haciendo esto por una razón. Incluso si no se puede hacer nada respecto al problema, se lo estás diciendo lo antes posible para que estén bien informados. + +La mejor manera de informar a alguien sobre un problema es ofrecer una solución al mismo tiempo. La segunda mejor manera es pedirles ayuda con el problema. Si hay peligro de que no te crean, deberías obtener algún respaldo para tu afirmación. + +Una de las cosas más desagradables y comunes que tendrás que decir es: 'El cronograma tendrá que retrasarse'. El programador consiente odia decir esto, pero debe hacerlo lo antes posible. No hay nada peor que posponer la acción cuando se retrasa un hito, incluso si la única acción es informar a todos. Al hacer esto, es mejor hacerlo como equipo, al menos en espíritu, si no físicamente. Querrás la opinión de tu equipo tanto sobre la situación actual como sobre lo que se puede hacer al respecto, y el equipo tendrá que enfrentar las consecuencias contigo. + +Siguiente [¿Cómo Lidiar con Mitos Gerenciales?](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/es/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md b/es/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md new file mode 100644 index 0000000..a38de21 --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -0,0 +1,13 @@ +# ¿Cómo Lidiar con Mitos Gerenciales? +[//]: # (Version:1.0.1) +La palabra *mito* a veces significa ficción, pero tiene una connotación más profunda. También se refiere a una historia de significado religioso que explica el universo y la relación del ser humano con él. Los gerentes tienden a olvidar lo que aprendieron como programadores y creen en ciertos mitos. Sería tan grosero e infructuoso tratar de convencerlos de que estos mitos son falsos como intentar desilusionar a una persona devotamente religiosa de sus creencias. Por esa razón, debes reconocer estas creencias como mitos: + +- Siempre es mejor tener más documentación. (La quieren, pero no quieren que gastes tiempo en ello). +- Los programadores pueden ser equiparados. (Los programadores varían en un orden de magnitud). +- Se pueden agregar recursos a un proyecto atrasado para acelerarlo. (El costo de la comunicación con las nuevas personas suele ser más agotador que útil). +- Es posible estimar el desarrollo de software de manera confiable. (Ni siquiera es teóricamente posible). +- La productividad de los programadores se puede medir en términos de algún métrico simple, como líneas de código. (Si la concisión es poder, las líneas de código son malas, no buenas). + +Si tienes la oportunidad, puedes intentar explicar estas cosas, pero no te sientas mal si no tienes éxito y no dañes tu reputación enfrentando estos mitos de manera beligerante. Cada uno de estos mitos refuerza la idea del gerente de que tienen algún control real sobre lo que está sucediendo. La verdad es que los gerentes facilitan si son buenos y obstaculizan si son malos. + +Siguiente [¿Cómo Lidiar con el Caos Organizacional?](11-How-to-Deal-with-Organizational-Chaos.md) \ No newline at end of file diff --git a/es/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md b/es/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md new file mode 100644 index 0000000..3b57ccf --- /dev/null +++ b/es/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md @@ -0,0 +1,11 @@ +# ¿Cómo Lidiar con el Caos Organizacional? +[//]: # (Version:1.0.1) +A menudo hay breves períodos de gran caos organizativo, como despidos, compras, salidas a bolsa, despidos, nuevas contrataciones, y así sucesivamente. Esto desconcierta a todos, pero quizás un poco menos al programador cuya autoestima personal se basa en la capacidad en lugar de en el puesto. El caos organizativo es una gran oportunidad para que los programadores ejerzan su poder mágico. He guardado esto para el final porque es un profundo secreto tribal. Si no eres programador, por favor, deja de leer ahora. + +> Los ingenieros tienen el poder de crear y sostener. + +Las personas no ingenieras pueden dar órdenes, pero en una empresa de software típica, no pueden crear ni mantener nada sin ingenieros, al igual que los ingenieros generalmente no pueden vender un producto o administrar un negocio de manera efectiva. Este poder es resistente a casi todos los problemas asociados con el caos organizativo temporal. Cuando lo tienes, deberías ignorar completamente el caos y continuar como si nada estuviera sucediendo. Puede que, por supuesto, te despidan, pero si eso sucede, probablemente puedas conseguir un nuevo trabajo gracias al poder mágico. Más comúnmente, alguna persona estresada que no tiene el poder mágico entrará en tu espacio de trabajo y te pedirá que hagas algo estúpido. Si realmente estás seguro de que es estúpido, es mejor sonreír y asentir hasta que se vayan y luego continuar haciendo lo que sabes que es lo mejor para la empresa. + +Si eres un líder, dile a tu equipo que haga lo mismo y diles que ignoren lo que les diga cualquier otra persona. Este curso de acción es lo mejor para ti personalmente y lo mejor para tu empresa o proyecto. + +Siguiente [Glosario](../../GLOSSARY.md) diff --git a/es/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/es/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..d77b9f3 --- /dev/null +++ b/es/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# ¿Cómo Distinguir lo Difícil de lo Imposible? +[//]: # (Version:1.0.1) +Es nuestra labor realizar lo difícil y discernir lo imposible. Desde el punto de vista de la mayoría de los programadores en activo, algo es imposible si no puede crecer a partir de un sistema simple o no puede estimarse. Bajo esta definición, lo que se llama investigación es imposible. Un gran volumen de simple trabajo es difícil, pero no necesariamente imposible. + +La distinción no es caprichosa, porque es posible que se te pida hacer lo que es prácticamente imposible, ya sea desde un punto de vista científico o de ingeniería de software. En ese caso, tu labor es ayudar al emprendedor a encontrar una solución razonable, que sea simplemente difícil y que logre la mayor parte de lo que deseaban. Una solución es simplemente difícil cuando puede programarse con confianza y se comprenden los riesgos. + +Es imposible satisfacer un requisito vago, como "Construir un sistema que calcule el peinado y color de cabello más atractivo para cualquier persona". Si el requisito puede definirse con más precisión, a menudo se convierte en simplemente difícil, como "Construir un sistema para calcular un peinado y color de cabello atractivos para una persona, permitirles previsualizarlo y realizar cambios, y lograr que la satisfacción del cliente basada en el estilo original sea tan grande que ganemos mucho dinero". Si no hay una definición clara del éxito, no tendrás éxito. + +Siguiente [¿Cómo Utilizar Lenguajes Incorporados?](02-How-to-Utilize-Embedded-Languages.md) diff --git a/es/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md b/es/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md new file mode 100644 index 0000000..2a30f8d --- /dev/null +++ b/es/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -0,0 +1,11 @@ +# ¿Cómo Utilizar Lenguajes Incorporados? +[//]: # (Version:1.0.1) +Incrustar un lenguaje de programación en un sistema tiene una fascinación casi erótica para un programador. Es uno de los actos más creativos que se pueden realizar. Hace que el sistema sea tremendamente poderoso. Te permite ejercer tus habilidades más creativas y prometeicas. Convierte al sistema en tu amigo. + +Los mejores editores de texto del mundo tienen todos lenguajes incrustados. Esto se puede utilizar en la medida en que la audiencia prevista pueda dominar el lenguaje. Por supuesto, el uso del lenguaje puede ser opcional, como ocurre en los editores de texto, para que los iniciados lo utilicen y los demás no tengan que hacerlo. + +Yo y muchos otros programadores hemos caído en la trampa de crear lenguajes incrustados con propósitos especiales. Caí en ella dos veces. Ya existen muchos lenguajes diseñados específicamente para ser lenguajes incrustados. Deberías pensarlo dos veces antes de crear uno nuevo. + +La verdadera pregunta que uno debe hacerse antes de incrustar un lenguaje es: ¿Esto funciona con o en contra de la cultura de mi audiencia? Si tu audiencia prevista es exclusivamente no programadores, ¿cómo les ayudará? Si tu audiencia prevista es exclusivamente programadores, ¿preferirían una interfaz de programación de aplicaciones (API)? ¿Y qué lenguaje será? Los programadores no quieren aprender un nuevo lenguaje que se use de manera estrecha; pero si se integra con su cultura, no tendrán que pasar mucho tiempo aprendiéndolo. Es un placer crear un nuevo lenguaje. Pero no deberíamos dejar que eso nos ciegue a las necesidades del usuario. A menos que tengas algunas necesidades e ideas verdaderamente originales, ¿por qué no usar un lenguaje existente para aprovechar la familiaridad que los usuarios ya tienen con él? + +Siguiente [Elección de Lenguajes](03-Choosing-Languages.md) diff --git a/es/3-Advanced/Technical-Judgment/03-Choosing-Languages.md b/es/3-Advanced/Technical-Judgment/03-Choosing-Languages.md new file mode 100644 index 0000000..cc8715e --- /dev/null +++ b/es/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -0,0 +1,15 @@ +# Elección de Lenguajes +[//]: # (Version:1.0.1) +El programador solitario que ama su trabajo (un hacker) puede elegir el mejor lenguaje para la tarea. La mayoría de los programadores que trabajan tienen muy poco control sobre el lenguaje que usarán. Generalmente, este tema lo dictan jefes de cabello puntiagudo que toman decisiones políticas en lugar de decisiones tecnológicas y carecen del valor para promover una herramienta no convencional incluso cuando saben, a menudo con conocimiento de primera mano, que la herramienta menos aceptada es la mejor. En otros casos, el beneficio muy real de la unidad entre el equipo, y en cierta medida con una comunidad más amplia, excluye la elección por parte del individuo. A menudo, los gerentes se ven impulsados por la necesidad de poder contratar programadores con experiencia en un determinado lenguaje. Sin duda, están sirviendo lo que perciben como los mejores intereses del proyecto o la empresa, y deben ser respetados por eso. Sin embargo, personalmente creo que esta es la práctica común más derrochadora y errónea que es probable que encuentres. + +Pero, por supuesto, las cosas nunca son unidimensionales. Incluso si se impone un lenguaje central y está fuera de tu control, a menudo ocurre que las herramientas y otros programas se pueden y deben escribir en un lenguaje diferente. Si se va a incrustar un lenguaje (¡y siempre debes considerarlo!), la elección del lenguaje dependerá en gran medida de la cultura de los usuarios. Uno debería aprovechar esto para servir a su empresa o proyecto utilizando el mejor lenguaje para el trabajo, y al hacerlo, hacer que el trabajo sea más interesante. + +Los lenguajes de programación realmente deberían llamarse notaciones, ya que aprender uno no es tan difícil como aprender un lenguaje natural. Para principiantes y algunos externos, 'aprender un nuevo lenguaje' parece una tarea desalentadora; pero después de tener tres bajo el cinturón, realmente es solo cuestión de familiarizarse con las bibliotecas disponibles. Uno tiende a pensar en un sistema grande que tiene componentes en tres o cuatro lenguajes como una mezcla desordenada; pero sostengo que dicho sistema es en muchos casos más fuerte que un sistema de un solo lenguaje en varios aspectos: + +- Necesariamente hay un acoplamiento débil entre los componentes escritos en diferentes notaciones (aunque quizás no interfaces limpias). +- Puedes evolucionar a un nuevo lenguaje/plataforma fácilmente reescribiendo cada componente individualmente. +- Un lenguaje puede no ser adecuado para el sistema en general; tener varios lenguajes para tus módulos te permite elegir la herramienta adecuada para el trabajo. + +Algunos de estos efectos pueden ser solo psicológicos, pero la psicología importa. Al final, los costos de la tiranía del lenguaje superan cualquier ventaja que pueda proporcionar. + +Siguiente [Comprometerse Sabiamente - ¿Cómo Combatir la Presión del Cronograma?](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/es/5-Bibliography.md b/es/5-Bibliography.md new file mode 100644 index 0000000..7a89400 --- /dev/null +++ b/es/5-Bibliography.md @@ -0,0 +1,32 @@ +# Apéndice A - Bibliografía/Sitografía + +[//]: # (Version:1.0.0) +## Libros + +[Rules00] Guy Kawasaki, Michelle Moreno y Gary Kawasaki. 2000. HarperBusiness. "Reglas para los Revolucionarios: El Manifiesto Capitalista para Crear y Comercializar Nuevos Productos y Servicios." + +[RDev96] Steve McConnell. 1996. Microsoft Press. Redmond, Washington. "Desarrollo Rápido: Domando Programas de Software Descontrolados." + +[CodeC93] Steve McConnell. 1993. Microsoft Press. Redmond, Washington. "Código Completo." + +[XP99] Kent Beck. 1999. 0201616416. Addison-Wesley. "Programación Extrema Explicada: Aceptar el Cambio." + +[PlanXP00] Kent Beck y Martin Fowler. 2000. 0201710919. Addison-Wesley. "Planificación de la Programación Extrema." + +[Prag99] Andrew Hunt, David Thomas y Ward Cunningham. 1999. 020161622X. Addison-Wesley. "El Programador Pragmático: Del Aprendiz al Maestro." + +[Stronger] Friedrich Nietzsche. 1889. "Crepúsculo de los ídolos", "Máximas y Flechas", sección 8.. + +## Sitios web + +[PGSite] Paul Graham. 2002. Artículos en su sitio web: [http://www.paulgraham.com/articles.html](http://www.paulgraham.com/articles.html). Todos ellos, pero especialmente "Venciendo a los Promedios". + +[Hacker] Eric S. Raymond. 2003. Cómo Convertirse en un Hacker. [http://www.catb.org/~esr/faqs/hacker-howto.html](http://www.catb.org/~esr/faqs/hacker-howto.html). + +[HackDict] Eric S. Raymond. 2003. El Nuevo Diccionario del Hacker. [http://catb.org/esr/jargon/jargon.html](http://catb.org/esr/jargon/jargon.html). + +[ExpCS] Edsger W. Dijkstra. 1986. ¿Qué tan experimental es la Ciencia de la Computación? [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF). + +[Knife] Edsger W. Dijkstra. 1984. Sobre una brecha cultural. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF). + +Siguiente [Historia](6-History.md) \ No newline at end of file diff --git a/es/6-History.md b/es/6-History.md new file mode 100644 index 0000000..8278c5b --- /dev/null +++ b/es/6-History.md @@ -0,0 +1,43 @@ +# Apéndice B - Historia +[//]: # (Version:1.0.0) +## Mudarse a Github + +Esta redacción se ha creado como un repositorio en Github para que pueda compartirse, actualizarse y mejorarse fácilmente. Se copió de [http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm) by [Braydie Grove](https://github.com/braydie). Se trasladó a Github en enero de 2016. + +## Solicitud de comentarios o ampliación + +Por favor, envíame cualquier comentario que tengas sobre este ensayo. Considero todas las sugerencias, muchas de las cuales ya han mejorado este ensayo. + +He colocado este ensayo bajo la Licencia de Documentación Libre de GNU. Esta licencia no está específicamente diseñada para ensayos. Los ensayos suelen tener la intención de ser argumentos coherentes y convincentes escritos desde un solo punto de vista con una sola voz. Espero que este ensayo sea una lectura corta y agradable. + +También espero que sea instructivo. Aunque no es un libro de texto, está dividido en muchas secciones pequeñas a las que se pueden agregar libremente nuevas secciones. Si así lo desea, se le anima a expandir este ensayo según lo considere necesario, sujeto a las disposiciones de la Licencia. + +Puede ser arrogancia imaginar que este documento merece ser ampliado, pero la esperanza es eterna. Estaría feliz si se ampliara de las siguientes maneras: + +La adición de una lista de lecturas completa para cada sección. +La adición de más y mejores secciones. +Traducción a otros idiomas, incluso si es solo por sección. +Críticas o comentarios incrustados en el texto. +La capacidad de construir en diferentes formatos, como formatos de palma y HTML mejorado. + +Si me informa sobre su trabajo, lo consideraré y puedo incluirlo en versiones posteriores que produzca, sujeto a las disposiciones de la Licencia. Por supuesto, puede producir sus propias versiones de este documento sin mi conocimiento, como se explica en la Licencia. + +Gracias. + +Robert L. Read + +## Versión original + +La versión original de este documento fue iniciada por Robert L. Read en el año 2000 y publicada por primera vez electrónicamente en Samizdat Press.(http://Samizdat.mines.edu) en 2002. Está dedicado a los programadores de Hire.com. + +Después de que este artículo fue mencionado en Slashdot en 2003, alrededor de 75 personas me enviaron correos electrónicos con sugerencias y correcciones. Agradezco a todos ellos. Hubo mucha duplicación, pero las siguientes personas hicieron sugerencias importantes o fueron las primeras en encontrar un error que corregí: Morgan McGuire, David Mason, Tom Moertel, Ninja Programmer (145252) en Slashdot, Ben Vierck, Rob Hafernik, Mark Howe, Pieter Pareit, Brian Grayson, Zed A. Shaw, Steve Benz, Maksim Ioffe, Andrew Wu, David Jeschke y Tom Corcoran. + +Finalmente, me gustaría agradecer a Christina Vallery, cuya edición y corrección de pruebas mejoraron significativamente el segundo borrador, y a Wayne Allen, quien me animó a iniciar esto. + +## Biografía del Autor Original + +Robert L. Read vive en Austin, Texas, con su esposa y sus dos hijos. Actualmente es Ingeniero Principal en Hire.com, donde ha trabajado durante cuatro años. Antes de eso, fundó 4R Technology, que creó una herramienta de control de calidad basada en el análisis de imágenes por escáner para la industria papelera. + +Rob obtuvo un doctorado de la Universidad de Texas en Austin en 1995 en Ciencias de la Computación relacionada con la teoría de bases de datos. En 1987 recibió una licenciatura en Ciencias de la Computación de la Universidad Rice. Ha sido programador remunerado desde la edad de 16 años. + +Siguiente [Licencia](LICENSE.md) diff --git a/es/7-Contributions.md b/es/7-Contributions.md new file mode 100644 index 0000000..cfd31da --- /dev/null +++ b/es/7-Contributions.md @@ -0,0 +1,33 @@ +# Contribuciones +[//]: # (Version:1.0.0) +Este repositorio tiene como objetivo ser un proyecto impulsado por la comunidad, y tu participación en última instancia ayudará a mejorar la calidad de esta guía. + +## ¿Qué puedo hacer para contribuir? + +Hay varias formas de contribuir a "Cómo ser un programador". + +- Ideas para nuevas secciones +- Mejoras en secciones existentes +- Identificación de errores tipográficos u otros problemas en las secciones +- Contribuir con enlaces adicionales a recursos para las secciones +- Sugerencias generales para mejorar el proyecto +- Proporcionar traducciones de la guía + +## Traducciones + +Actualmente, esta guía ha sido traducida del inglés a los siguientes idiomas: + +- Chino por [ahangchen](https://github.com/ahangchen) +- Español por [Maximiliano Murua](https://gitlab.com/maximiliano.murua) + +**Si proporcionas la traducción inicial de la guía a otro idioma, eres elegible para convertirte en colaborador de este proyecto para ayudar a mantener y revisar los cambios realizados en la traducción.** + +## Colaboradores + +GitHub tiene una lista de todos los [colaboradores](https://github.com/braydie/HowToBeAProgrammer/graphs/contributors) a este proyecto. + +## Editorial y traslado a GitHub + +[Braydie Grove](https://www.github.com/braydie) ha aceptado servir como editor en jefe. + +Braydie trasladó el ensayo original a MarkDown y creó el repositorio. \ No newline at end of file diff --git a/es/GLOSSARY.md b/es/GLOSSARY.md new file mode 100644 index 0000000..15d5cae --- /dev/null +++ b/es/GLOSSARY.md @@ -0,0 +1,131 @@ +# Glossary +[//]: # (Version:1.0.0) +Este es un glosario de términos tal como se usan en este ensayo. Estos términos no tienen necesariamente un significado estandarizado para otras personas. Eric S. Raymond ha compilado un glosario[HackerDict] masivo e informativo que sorprendentemente puede leerse con placer de principio a fin una vez que se puede apreciar una fracción de él. + +### unk-unk + +Jerga que significa desconocido-desconocido. Problemas que actualmente ni siquiera pueden ser conceptualizados y que robarán tiempo al proyecto y arruinarán el cronograma. + +### printlining + +La inserción temporal de declaraciones en un programa que imprime información sobre la ejecución del programa con el fin de depurarlo. + +### logging + +La práctica de escribir un programa de manera que pueda producir un registro de salida configurable que describa su ejecución. + +### divide and conquer + +Una técnica de diseño top-down y, lo que es más importante, de depuración, que consiste en la subdivisión de un problema o misterio en problemas o misterios progresivamente más pequeños. + +### vapour + +Promesas ilusorias y a menudo engañosas de software que aún no está a la venta y, con la misma frecuencia, nunca se materializará en algo sólido. + +### boss + +La persona que asigna tus tareas. En algunos casos, el usuario es el jefe. + +### tribe + +Las personas con las que compartes lealtad hacia un objetivo común. + +### low-hanging fruit + +Grandes mejoras que cuestan poco. + +### Entrepreneur + +El iniciador de proyectos. + +### business + +Un grupo de personas organizado para ganar dinero. + +### company + +Un grupo de personas organizado para ganar dinero. + +### scroll blindness + +El efecto de no poder encontrar la información que necesitas porque está enterrada en demasiada información, menos interesante. + +### wall-clock + +El tiempo real medido por un reloj en la pared, en contraposición al tiempo de CPU. + +### bottleneck + +La limitación más importante en el rendimiento de un sistema. Una constricción que limita el rendimiento. + +### master + +Una pieza única de información de la cual se derivan todas las copias en caché y que sirve como la definición oficial de esos datos. + +### heap allocated + +La memoria se puede decir que está asignada en el montículo (heap) cuando el mecanismo para liberarla es complicado. + +### garbage + +Memoria que está siendo ocupada por objetos que tu aplicación ya no necesita. + +### garbage collector + +Sistema de reciclaje de basura. + +### memory leak + +La colección no deseada de referencias a objetos que impide la recolección de basura (¡o un error en el recolector de basura o en el sistema de gestión de memoria!) y que provoca que el programa aumente gradualmente sus demandas de memoria con el tiempo. + +### Extreme Programming + +Un estilo de programación que hace hincapié en la comunicación con el cliente y en las pruebas automatizadas. + +### hitting the wall + +Quedarse sin un recurso específico, causando una degradación abrupta del rendimiento en lugar de gradual. + +### speculative programming + +Producir una característica antes de saber realmente si esa característica será útil. + +### information hiding + +Un principio de diseño que busca mantener las cosas independientes y desacopladas mediante el uso de interfaces que exponen la menor cantidad de información posible. + +### object-oriented programming + +Un estilo de programación que enfatiza la gestión del estado dentro de los objetos. + +### communication languages + +Un lenguaje diseñado principalmente para la estandarización en lugar de la ejecución. + +### boxes and arrows + +Un estilo relajado e informal para hacer diagramas que consiste en cajas y flechas dibujadas entre esas cajas para mostrar las relaciones. Esto contrasta con las metodologías de diagramas formales, como UML. + +### lingua franca + +Un lenguaje tan popular que se convierte en un estándar de facto para su campo, como lo fue el francés para la diplomacia internacional en algún momento. + +### buy vs. build + +Un adjetivo que describe una elección entre gastar dinero en software o escribirlo tú mismo. + +### mere work + +Trabajo que requiere poca creatividad y conlleva poco riesgo. El simple trabajo se puede estimar fácilmente. + +### programming notation + +Un sinónimo de lenguaje de programación que enfatiza la naturaleza matemática de los lenguajes de programación y su relativa simplicidad en comparación con los lenguajes naturales. + +### strawman + +Un documento destinado a ser el punto de partida de una discusión técnica. Un "strawman" puede llevar a un "stickman", "tinman", "woodman", "ironman", etc. + +### white-paper + +Un documento informativo que a menudo tiene la intención de explicar o vender un producto o idea a una audiencia diferente de los programadores de ese producto o idea. diff --git a/es/LICENSE.md b/es/LICENSE.md new file mode 100644 index 0000000..529d2e4 --- /dev/null +++ b/es/LICENSE.md @@ -0,0 +1,10 @@ + +## Licencia Creative Commons Atribución-CompartirIgual + +"How To Be A Programmer: Community Version" de Robert L. Read con la comunidad está bajo la Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional. + +En la actualidad, este trabajo será editado por Braydie Grove y Robert L. Read. + +Haremos intentos razonables para mantener las atribuciones adecuadas de las contribuciones en la sección titulada "Contribuciones". Si realizas una solicitud de extracción (pull request) con una contribución significativa, por favor, agrega una descripción muy breve de tu contribución en esa sección. + +Creative Commons License
Cómo ser un programador: Versión Comunitaria de Robert L. Read con la Comunidad está bajo una Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional. diff --git a/es/README.md b/es/README.md new file mode 100644 index 0000000..403a286 --- /dev/null +++ b/es/README.md @@ -0,0 +1,103 @@ +# Cómo ser un Programador: Versión Comunitaria +[//]: # (Version:1.0.0) +Robert L. Read con la Comunidad + +Copyright 2002, 2003, 2016 Robert L. Read + +Bajo licencia [Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional](http://creativecommons.org/licenses/by-sa/4.0/). + +## Introducción +Ser un buen programador es difícil y noble. La parte más difícil de hacer realidad la visión colectiva de un proyecto de software es lidiar con los compañeros de trabajo y los clientes. Escribir programas de computadora es importante y requiere gran inteligencia y habilidad. Pero realmente es un juego de niños en comparación con todo lo demás que un buen programador debe hacer para lograr que un sistema de software sea exitoso tanto para el cliente como para los numerosos colegas de los que es parcialmente responsable. En este ensayo, intento resumir lo más concisamente posible las cosas que desearía que alguien me hubiera explicado cuando tenía veintiún años. + +Esto es muy subjetivo y, por lo tanto, este ensayo está destinado a ser personal y algo subjetivo. Me limito a problemas que un programador es muy probable que tenga que enfrentar en su trabajo. Muchos de estos problemas y sus soluciones son tan generales para la condición humana que probablemente pareceré moralista. Espero que, a pesar de esto, este ensayo sea útil. + +La programación de computadoras se enseña en cursos. Los excelentes libros: "The Pragmatic Programmer" [Prag99], "Code Complete" [CodeC93], "Rapid Development" [RDev96] y "Extreme Programming Explained" [XP99] enseñan programación de computadoras y los problemas más amplios de ser un buen programador. Los ensayos de Paul Graham [PGSite] y Eric Raymond [Hacker] deben ser leídos antes o junto con este artículo. Este ensayo difiere de esas obras excelentes al enfatizar problemas sociales y resumir de manera integral todo el conjunto de habilidades necesarias según mi punto de vista. + +En este ensayo, el término "jefe" se utiliza para referirse a quien te asigna proyectos. Utilizo las palabras negocio, empresa y tribu de manera sinónima, excepto que negocio denota hacer dinero, empresa denota el entorno laboral moderno y tribu es generalmente la gente con la que compartes lealtad. + +Bienvenido a la tribu. + +## Contenidos + +1. [Principiante](1-Beginner) + - Habilidades Personales + - [Aprender a Depurar](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [¿Cómo depurar dividiendo el espacio del problema?](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [¿Cómo eliminar un error?](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [¿Cómo Depurar Utilizando un Registro (Log)?](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [¿Cómo Entender Problemas de Rendimiento?](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [¿Cómo Solucionar Problemas de Rendimiento?](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [¿Cómo Optimizar Bucles?](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [¿Cómo Manejar el Costo de la Entrada/Salida (E/S)?](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [¿Cómo Gestionar la Memoria?](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [¿Cómo Manejar Errores Intermitentes?](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [¿Cómo Aprender Habilidades de Diseño?](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [¿Cómo Realizar Experimentos?](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - Habilidades de Equipo + - [¿Por qué es importante la estimación?](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [¿Cómo estimar el tiempo de programación?](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [¿Cómo encontrar información?](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [¿Cómo utilizar a las personas como fuentes de información?](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [¿Cómo documentar de manera inteligente?](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [¿Cómo trabajar con un código deficiente?](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [¿Cómo Utilizar el Control de Código Fuente?](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [¿Cómo realizar pruebas unitarias?](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [Tomarse descansos cuando te sientes bloqueado](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [¿Cómo reconocer cuándo es hora de ir a casa?](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [¿Cómo lidiar con personas difíciles?](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [Intermedio](2-Intermediate) + - Habilidades Personales + - [¿Cómo mantenerse motivado?](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [¿Cómo ser ampliamente confiado?](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [¿Cómo hacer equilibrio entre tiempo y espacio?](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [¿Cómo realizar pruebas de resistencia?](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [¿Cómo equilibrar brevedad y abstracción?](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [¿Cómo aprender nuevas habilidades?](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Aprender a escribir](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [¿Cómo Hacer pruebas de integración?](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Idiomas de comunicación](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [Herramientas pesadas](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [¿Cómo analizar datos?](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - Habilidades de Equipo + - [¿Cómo gestionar el tiempo de desarrollo?](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [¿Cómo gestionar los riesgos del software de terceros?](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [¿Cómo gestionar a los consultores?](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [¿Cómo comunicar la cantidad adecuada?](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [¿Cómo disentir honradamente y salir airosos?](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - Juicio + - [¿Cómo equilibrar la calidad contra el tiempo de desarrollo?](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [¿Cómo gestionar la dependencia del sistema de software?](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [¿Cómo decidir si el software es demasiado inmaduro?](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [¿Cómo tomar una decisión de compra frente a desarrollo interno?](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [¿Cómo crecer profesionalmente?](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [¿Cómo evaluar a los candidatos en una entrevista?](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [¿Cómo saber cuándo aplicar conceptos avanzados de ciencias de la computación?](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [¿Cómo hablar con personas no ingenieras?](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [Avanzado](3-Advanced) + - Juicio Tecnológico + - [¿Cómo distinguir lo difícil de lo imposible?](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [¿Cómo utilizar lenguajes incorporados?](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Elección de lenguajes](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - Comprometerse Sabiamente + - [¿Cómo combatir la presión del cronograma?](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [¿Cómo eentender al usuario?](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [¿Cómo obtener un ascenso?](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - Sirviendo a tu Equipo + - [¿Cómo desarrollar el talento?](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [¿Cómo elegir en qué trabajar?](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [¿Cómo obtener lo mejor de tus compañeros de equipo?](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [¿Cómo dividir problemas?](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [¿Cómo manejar tareas aburridas?](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [¿Cómo obtener apoyo para un proyecto?](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [¿Cómo hacer crecer un sistema?](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [¿Cómo comunicarse bien?](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [¿Cómo decir cosas que la gente no quiere escuchar?](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [¿Cómo lidiar con mitos gerenciales?](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [¿Cómo lidiar con el caos organizacional?](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [Glosario](GLOSSARY.md) +5. [Apéndice A - Bibliografía/Sitios web](5-Bibliography.md) +6. [Apéndice B - Historia (Hasta enero de 2016)](6-History.md) +6. [Apéndice C - Contribuciones (Hasta enero de 2016)](7-Contributions.md) + + +Creative Commons License
Cómo ser un programador: Versión Comunitaria de Robert L. Read con la Comunidad está bajo una Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional. diff --git a/es/SUMMARY.md b/es/SUMMARY.md new file mode 100644 index 0000000..20ff270 --- /dev/null +++ b/es/SUMMARY.md @@ -0,0 +1,80 @@ +# Resumen +[//]: # (Version:1.0.0) +* [Principiante](1-Beginner/README.md) + * Habilidades Personales + * [Aprender a Depurar](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + * [¿Cómo depurar dividiendo el espacio del problema?](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + * [¿Cómo eliminar un error?](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + * [¿Cómo depurar utilizando un registro (Log)?](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + * [¿Cómo entender problemas de rendimiento?](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + * [¿Cómo solucionar problemas de rendimiento?](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + * [¿Cómo optimizar bucles?](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + * [¿Cómo manejar el costo de la entrada/salida (E/S)?](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + * [¿Cómo gestionar la memoria?](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + * [¿Cómo manejar errores intermitentes?](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + * [¿Cómo aprender habilidades de diseño?](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + * [¿Cómo realizar experimentos?](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + * Habilidades de Equipo + * [¿Por qué es importante la estimación?](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + * [¿Cómo estimar el tiempo de programación?](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + * [¿Cómo encontrar información?](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + * [¿Cómo utilizar a las personas como fuentes de información?](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + * [¿Cómo documentar de manera inteligente?](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + * [¿Cómo trabajar con un código deficiente?](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + * [¿Cómo Utilizar el Control de Código Fuente?](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + * [¿Cómo realizar pruebas unitarias?](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + * [Tomarse descansos cuando te sientes bloqueado](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + * [¿Cómo reconocer cuándo es hora de ir a casa?](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + * [¿Cómo lidiar con personas difíciles?](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +* [Intermedio](2-Intermediate/README.md) + * Habilidades Personales + * [¿Cómo mantenerse motivado?](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + * [¿Cómo ser ampliamente confiado?](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + * [¿Cómo hacer equilibrio entre tiempo y espacio?](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + * [¿Cómo realizar pruebas de resistencia?](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + * [¿Cómo equilibrar brevedad y abstracción?](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + * [¿Cómo aprender nuevas habilidades?](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + * [Aprender a escribir](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + * [¿Cómo Hacer pruebas de integración?](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + * [Idiomas de comunicación](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + * [Herramientas pesadas](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + * [¿Cómo analizar datos?](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + * Habilidades de Equipo + * [¿Cómo gestionar el tiempo de desarrollo?](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + * [¿Cómo gestionar los riesgos del software de terceros?](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + * [¿Cómo gestionar a los consultores?](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + * [¿Cómo comunicar la cantidad adecuada?](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + * [¿Cómo disentir honradamente y salir airosos?](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + * Juicio + * [¿Cómo equilibrar la calidad contra el tiempo de desarrollo?](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + * [¿Cómo gestionar la dependencia del sistema de software?](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + * [¿Cómo decidir si el software es demasiado inmaduro?](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + * [¿Cómo tomar una decisión de compra frente a desarrollo interno?](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + * [¿Cómo crecer profesionalmente?](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + * [¿Cómo evaluar a los candidatos en una entrevista?](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + * [¿Cómo saber cuándo aplicar conceptos avanzados de ciencias de la computación?](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + * [¿Cómo hablar con personas no ingenieras?](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +* [Avanzado](3-Advanced/README.md) + * Juicio Tecnológico + * [¿Cómo distinguir lo difícil de lo imposible?](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + * [¿Cómo utilizar lenguajes incorporados?](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + * [Elección de lenguajes](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + * Comprometerse Sabiamente + * [¿Cómo combatir la presión del cronograma?](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + * [¿Cómo eentender al usuario?](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + * [¿Cómo obtener un ascenso?](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + * Sirviendo a tu Equipo + * [¿Cómo desarrollar el talento?](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + * [¿Cómo elegir en qué trabajar?](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + * [¿Cómo obtener lo mejor de tus compañeros de equipo?](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + * [¿Cómo dividir problemas?](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + * [¿Cómo manejar tareas aburridas?](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + * [¿Cómo obtener apoyo para un proyecto?](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + * [¿Cómo hacer crecer un sistema?](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + * [¿Cómo comunicarse bien?](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + * [¿Cómo decir cosas que la gente no quiere escuchar?](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + * [¿Cómo lidiar con mitos gerenciales?](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + * [¿Cómo lidiar con el caos organizacional?](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +* [Apéndice A - Bibliografía/Sitios web](5-Bibliography.md) +* [Apéndice B - Historia (Hasta enero de 2016)](6-History.md) +* [Apéndice C - Contribuciones (Hasta enero de 2016)](7-Contributions.md) diff --git a/jp/1-Beginner/Personal-Skills/01-Learn-To-Debug.md b/jp/1-Beginner/Personal-Skills/01-Learn-To-Debug.md new file mode 100644 index 0000000..867820e --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -0,0 +1,21 @@ +# Learn to Debug +[//]: # (Version:1.0.0) +fobO̓vO}ɂȂ邽߂̊błB "debug"̍ŏ̈Ӗ̓G[菜ƂłAۂɏdvȈӖ́AvO̎s𒲂ׂĒׂ邱ƂłBʓIɃfobOłȂvO}[͖ڂ܂B + +z`ҁA݌vÁAG̗_ȂǂfobO{IƍlĺAvO}[𓭂Ă܂BvO}[͗zIȐEɏZł܂BȂłĂA\tgEFAЁAGNÛ悤ȑgDAтȂ̓ɂďꂽR[hɈ͂܂ĂȂ΂Ȃ܂B̃R[ĥقƂǂ͕sSłAsSɕĂ܂B̃R[h̎sŽ@\Ȃ΁A킸ȃov͂Ȃiɓ̂Ă܂B̏ꍇẢŽ͎ifobOjɂĂ̂ݓ܂B + +fobÓAvÔ̂ł͂ȂAvO̎sɊւ̂łBȂ\tgEFAЂ牽wꍇAʏ͂̃vO邱Ƃ͂ł܂BAR[hhLgɏĂȂꏊi}VŜNbV邱Ƃ͈ʓIősȗłjhLe[V~[gĂꏊ܂BʓIɂ́AG[쐬A񂾃R[h𒲂ׁAG[ǂ̂悤ɔ”\̂??킩܂BKRIɁA͂ȂĂƂO񂪂Ȃ萳ȂƁA邢͂Ȃ\ĂȂԂƂӖ܂Bɂ́A\[XR[h𒭂߂Ă閂@܂삷邱Ƃ܂BłȂꍇ́AfobOKv܂B + +vO̎sŽɂ́AR[hsẴR[hώ@łKv܂Bʂɕ\ẮA܂2‚̃CxgԂ̒x̂悤ɁAꂪڂɌ邱Ƃ܂B̏ꍇAR[ĥ‚̕ϐ̏ԁAۂɎsĂR[h̍sA܂͕Gȃf[^\ɂ킽ē̃AT[VێĂ邩ǂȂǁAڂɌȂ̂܂܂܂B̉Bꂽ͖̂炩ɂȂ΂Ȃ܂B + +svO "nnards"𒲂ׂʓIȕ@́Â悤ɕނł܂B + +- fobOc[gpāA +- Printlining - vOꎞIɕύX܂BʏAo͂slj܂B +- MO - vO̎sɉiIȃEBhEǑ`ō쐬܂B + +fobMOc[́A肵ėp”\ȏꍇ͑f炵łACeBOƃMO͂ɏdvłBfobOc[͌JɒxƂ邱Ƃ߁A‚łpłȂ”\܂BɁAfobOc[ɃvO̎s@ύX”\邽߁AKۓIł͂Ȃꍇ܂BŌɁA傫ȃf[^\ɑ΂AT[Ṽ`FbNAR[h̋LqAvO̎s̕ύXȂǁA‚̎ނ̃fobO܂BfobOc[肵ĂƂɃfobOc[gp@mĂƂ͗ǂƂłA2‚̕@gpł邱ƂdvłB + +‚̏S҂́AR[hύXKvƂɃfobOĂ܂B͗ł - ͒TIp̂悤Ȃ̂łBAȂ̓R[h˂hăWv邱Ƃw΂Ȃ΂Ȃ܂BȂ͂āAȂꎞIɍsƂ͉͂̂ȂƂ𗝉邱Ƃw΂Ȃ΂Ȃ܂B̋|ꍇ́A^[TĂB̋|ւ̕qȎn܂ŁA̗DꂽvO}[܂B + +Next [How to Debug by Splitting the Problem Space](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/jp/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md b/jp/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md new file mode 100644 index 0000000..cb561dd --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -0,0 +1,14 @@ +# How to Debug by Splitting the Problem Space +[//]: # (Version:1.0.0) +デバッグは楽しいです。なぜなら、それは謎で始まるからです。あなたは何かをすべきだと思うが、代わりに何かをする。それはいつも非常に簡単なわけではありません---私が与えることができる例は、実際に時々起こるものと比較して考案されます。デバッグには創造性と創意工夫が必要です。デバッグする単一のキーがある場合は、ミステリーで分割と征服のテクニックを使用することです。 + +たとえば、シーケンスで10個を実行するプログラムを作成したとします。あなたがそれを実行すると、クラッシュします。あなたがクラッシュするようにプログラムしていないので、今あなたは謎を持っています。出力を見ると、シーケンスの最初の7つが正常に実行されたことがわかります。最後の3つは出力から見えないので、今はあなたの謎は小さくなります: 'それは#8、#9、または#10の物に墜落しました。 + +どのようなものがクラッシュしたかを確認するために実験を設計できますか?確かに。 #8と#9の後に、デバッガを使用することもできますし、printline文(またはあなたが作業している言語に相当するもの)を追加することもできます。私たちがもう一度それを実行すると、「それは事9番に墜落しました」というような私の謎は小さくなるでしょう。いくつかの人々が問題に圧力をかけて一緒に働いているとき、最も重要な謎が何であるかを忘れるのは簡単です。 + +デバッグ技術として分割して克服する鍵は、アルゴリズム設計と同じです。ミステリーを途中で分割すると、何度も分割する必要はなくなります。迅速にデバッグすることができます。しかし、謎の真ん中は何ですか?これは、真の創造性と経験が生まれる場所です。 + +真の初心者にとって、考えられるすべてのエラーの領域は、ソースコード内のすべての行のように見えます。実行された行のスペース、データ構造、メモリ管理、外部コードとのやりとり、危険なコードなど、プログラムの他の次元を見るために後で開発するビジョンはありません。単純なコードです。経験豊富なプログラマーにとって、これらの他の次元は、間違っている可能性があるすべての事柄の不完全だが非常に有用な精神モデルを形成する。その精神モデルを持つことは、謎の真ん中を効果的に見つけるのに役立ちます。 + +間違っている可能性のある領域を均等に細分したら、エラーがどの領域にあるかを判断する必要があります。私のプログラムがクラッシュする単一の不明な行はどれですか?単純なケースでは、自分が実行しているプログラムの途中で実行されると判断した行の前または後に未知の行が実行されていますか? '通常、エラーが単一の行に存在するか、単一のブロックであるかを知ることは大変幸運なことではありません。しばしば、ミステリーは、「間違ったノードを指し示すポインタがそのグラフにあるか、またはそのグラフ内の変数を加算するアルゴリズムが機能しません」という場合があります。その場合は、分割された謎のどの部分を除去できるかを決定するために、グラフ内のポインタがすべて正しいことを確認する小さなプログラム。 +Next [How to Remove an Error](03-How-to-Remove-an-Error.md) diff --git a/jp/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md b/jp/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md new file mode 100644 index 0000000..7e353dc --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -0,0 +1,9 @@ +# How to Remove an Error +[//]: # (Version:1.0.0) +͈Ӑ}IɃvO̎sG[Csׂ璲ׂƂsׂ𕪂BAfobO̓oO菜ƂӖ܂BzIɂ́AR[hSɗAG[Sɕ\AC@unnIv̏uԂɓB܂BAȂ̃vOł́AŽ̂ȂꂽVXegp邱Ƃ߁AKłƂ͌܂B̃P[Xł́AR[hGł邽߁ASł͂܂B + +oOCɂ́AoOCŏ̕ύXƍlĂ܂BȂ͉PKvȑ̂̂邩܂BɂCȂłBxɈ‚̂ƁA‚̎ςȊwI@̗p悤ƂB̂߂̍ŗǂ̃vZX́AoOȒPɍČACvOKpĂvOĎsAoO݂ȂȂƂmF邱ƂłBAɂ͕̍sύXKv邩܂񂪁AoOC邽߂ɊTOI1‚̃Ag~bNȕύXKpKv܂B + +ɂ́Aۂɂ1‚̂悤Ɍ邢‚̃oO܂BoO`ĈxɏĈ͂ȂłBXAvOׂA܂͌̒҂Ӑ}̂słB̏ꍇAȂ͎̌oƔfsAR[hɎ̈Ӗ蓖ĂKv܂Bׂ肵ARgA炩̕@ł𖾊mɂ肵āAR[hȂ̈ӖɓK܂B́Aŏ̏ꏊɌ̊֐ɂ͓܂͏㋉̃XLłAۂ̐E͂΂Ζʓ|łBłȂVXeCKv邩܂B + +Next [How to Debug Using a Log](04-How-to-Debug-Using-a-Log.md) \ No newline at end of file diff --git a/jp/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md b/jp/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md new file mode 100644 index 0000000..e02f3e4 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -0,0 +1,12 @@ +# How to Debug Using a Log +[//]: # (Version:1.0.0) +*MO*́AOƌĂ΂A̗LvȃR[h𐶐悤ɃVXe쐬@łB * Printlining *͒PȁAʏ͈ꎞIȃO𐶐Ă܂BvO~O̒mĂ邽߁AΏS҂̓O𗝉ĎgpKv܂BVXe݌v҂́AVXe̕Ĝ߃O𗝉ĎgpKv܂BOɂĒ񋟂̗ʂ́AvOsĂԂ͗zIɍ\”\łȂ΂Ȃ܂BʂɁAOɂ3‚̊{Iȗ_܂B + +- ÓAČ̂oOiv_NV‹Ŕ̂́AeXg‹ł͍ČłȂoOȂǁjɊւLpȏ񋟂܂B +- ÓAXe[ggԂ̎Ԃ̌o߂ȂǁAptH[}XɊ֘A铝vуf[^񋟂ł܂B +- \”\ȏꍇAO͈ʓIȏLv`āA̖邽߂ɃR[hC/܂͍ăfvC邱ƂȂA\Ȃ̖fobO邱Ƃł܂B + +Oɏo͂ʂ́AƊȌ̊Ԃ̑Ë_łB񂪑ƃOɂȂA*XN[uCh*AKvȏ‚邱ƂȂ܂B񂪏ȂAKvȏ񂪊܂܂ĂȂ”\܂B̂߁Ao͂\”\ɂ邱Ƃ͔ɕ֗łBʏAO̊eR[h́A\[XR[ḧʒuAs”\ȏꍇ͂sXbhAs̐mȎAшʓIɁAϐ̒lAf[^IuWFNg̐Ȃǂ܂܂܂B̃OXe[gǵA\[XR[hŜɂ킽āAɎv@\_댯ȃR[h̎ɎU݂Ă܂BeXe[ggɃx蓖Ă邱ƂłAVXẽ݂xo͂悤ɐݒ肳Ăꍇɂ̂݃R[ho͂܂B\zɑΏ邽߂ɁAOXe[gg݌vKv܂BptH[}X𑪒肷Kv\܂B + +iIȃOꍇ́AOR[hɊւĈCsł悤ɂȂAꕔ̃fobOMOVXeɉivɒlj”\܂B +Next [How to Understand Performance Problems](05-How-to-Understand-Performance-Problems.md) diff --git a/jp/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md b/jp/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md new file mode 100644 index 0000000..156ff77 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -0,0 +1,11 @@ +# How to Understand Performance Problems +[//]: # (Version:1.0.0) +s̃VXẽptH[}X𗝉邱Ƃ́AfobOwK̂ƓR܂BȂR[h̃RXgSɐmɗĂĂAȂ̃R[h́AȂقƂǐłȂŽł鑼̃\tgEFAVXeĂяoł傤BAۂɂ́AptH[}X̖͈ʓIɃfobOقȂAȒPłB + +Ȃ₠Ȃ̌ڋqAVXeTuVXȇxxƍlĂƂ܂B悤ƂOɁAȂꂪx̂̐_f\zKv܂Bsɂ́Avt@COc[܂͓K؂ȃOgpāAԂ₻̑̃\[Xۂɔ₳Ăꏊ肵܂B̎Ԃ90R[h10ɔ₳ƂLȌt܂B͂ɃptH[}X̖ɑ΂o͔piI / Oj̏dvlj܂B̏ꍇAقƂǂ̏ꍇAI / O͂ӖŔ₳܂BI / OƃR[h̍10‚邱Ƃ́AȂ̃^f\z邽߂̑łB + +Rs[^VXe̐\ɂ͑̎Ã\[X܂B肷ŏ̃\[X́A* wall-clock time *łB́AvZɕKvȍvԂłBMO*EH[NbN*́Ãvt@COpIłȂ󋵂ŋN\s”\ȏ󋵂ɂ‚Ēʒmł邽߁AɏdvłBA͕K摜Ŝ\Ƃ͌ȂBꍇɂĂ͏Ԃ܂AۂɏȂ΂ȂȂRs[eBO‹ł́Aɑ̃vZbTb̂͂Ɨǂł傤BlɁA[Albg[Nш敝Af[^x[X܂͑̃T[o[ւ̃ANZX́AŏIIɃvZbTb͂邩ɍɂȂ”\܂B + +ꂽL\[X̋́AfbhbNƋQN”\܂BfbhbŃAsK؂ȓ⃊\[Xv̂߂ɏłȂƂłBQƂ́AR|[lgK؂ɃXPW[邱Ƃł͂܂BꂪׂĊ҂łꍇ́AvWFNg̊Jn炱̋𑪒肷@邱ƂőPłB̋NȂĂAMĕ\ł邱Ƃ͔ɗLpłB + +Next [How to Fix Performance Problems](06-How-to-Fix-Performance-Problems.md) diff --git a/jp/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md b/jp/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md new file mode 100644 index 0000000..a648693 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -0,0 +1,12 @@ +# How to Fix Performance Problems +[//]: # (Version:1.0.0) +قƂǂ̃\tgEFAvWFNǵAŏɃ[XꂽƂ10?100{̑xŔrIȒPɍ쐬ł܂Bs꓊܂ł̎Ԃ𔗂钆ŁAPvɍƂs\[VI邱Ƃ́AŌʓIłÃ\[VIł͂܂BAptH[}X̓[UreB̈ꕔłA΂΍ŏIIɂ͂TdɌKv܂B + +ɕGȃVXẽptH[}Xコ邽߂̌́A{glbN*⃊\[X̑啔ꏊ‚̂ɏ\ɕ͂邱ƂłBvZԂ̂킸1߂֐̍œKɂ͂܂Ӗ܂BoƂāAVXeVXȅdvȕȂƂ2{ƎvȂAOɐTdɍlKv܂Bʏ킱s@܂BύXɕKvȃeXgƕiۏ؂̓w͂ĂBꂼ̕ύXɂăeXg̕S܂̂ŁA‚̑傫ȕύX͂邩ɗDĂ܂B + +2{ɉṔAVXe̒Ŏɍȃ{glbN𔭌邽߂ɏȂƂčlAĕ͂Kv܂B + +̏ꍇAptH[}X̃{glbŃA𐔂ɁA𐔂A4Ŋ邱Ƃɂċ𐔂ɂȂ܂BƂ΁A[Vif[^x[XVXeɓK؂ȃCfbNXt邱ƂłǍsƁAȂƂ20{xȂȂǂ̃G[܂B̗ƂẮA[vŕsKvI / OsAsvȃfobOcAsKvȃ蓖āAɃptH[}XɊւĕĂȂCu₻̑̃TuVXegp邱Ƃ܂B̎̉P͎Xu|̉ʎvƌĂ΂A‚̗_񋟂邽߂ɊȒPɑIԂƂł܂B + +Ԃ牺ĂʕȂȂĂAȂ͉܂HāAȂ͂ƏɍsƂłA܂͖؂`bvBȉP𑱂邱ƂAVXeTuVXe^ɍĐ݌v邱Ƃł܂B íAV݌vłȂAiɂꂪǂlł邱Ƃ[ǂvO}[ƂĂ̂Ȃ̃XLgpD̋@łBjATuVXe̍Đ݌vɂ‚Ę_OɁAȂ̒Ă5?10{ǂ邩ǂɂ炸A +Next [How to Optimize Loops](07-How-to-Optimize-Loops.md) diff --git a/jp/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md b/jp/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md new file mode 100644 index 0000000..d748fff --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -0,0 +1,14 @@ +# How to Optimize Loops +[//]: # (Version:1.0.0) +ɂ́AsɎԂAĩ{glbNƂȂ郋[vċA֐邱Ƃ܂B[vOɁASɍ폜@邩ǂāA₵ĂBʂ̃ASY܂HɉvZȂ炻vZł܂H􂪌‚Ȃꍇ́A[vœK邱Ƃł܂B͊ȒPłB𓮂Bǂ̂ƂAɂ͓ƑnłȂAeނ̒qƕ\̔p̗KvƂȂ܂Bɂ‚̒Ă܂F + +- _Z폜܂B +- VubNsKvɊ蓖ĂȂłB +- 萔ꏏɐ܂肽݂܂B +- I / Oobt@ɈړB +- 􂵂ȂłB +- Ȍ^LXgȂłB +- CfbNXČvẐł͂ȂA|C^ړB + +̊ẽRXǵÃVXeɂĈقȂ܂B‚̃VXeł́ARpCƃn[hEFÂƂs܂BmŌIȃR[h́ÃvbgtH[̗KvƂR[hDĂ܂B +Next [How to Deal with I/O Expense](08-How-to-Deal-with-IO-Expense.md) diff --git a/jp/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md b/jp/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md new file mode 100644 index 0000000..f23ee8c --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -0,0 +1,13 @@ +# How to Deal with I/O Expense +[//]: # (Version:1.0.0) +̖ɑ΂āAvZbT̓n[hEFAfoCXƂ̒ʐMRXgɔׂčłB̃RXǵAʏI / OƏȗAlbg[NRXgAfBXNI / OAf[^x[XNGAt@CI / OAуvZbTɂ܂ߐڂȂn[hEFA̎gpȂǂ܂܂܂BāAȃVXe\z邱Ƃ́A΂΂‚̂‚[vŃR[hP邱ƁA܂̓ASYP邱ƂI / OP邱Ƃ̖łB + +I / OPɂ́ALbVOƕ\2‚̔Ɋ{IȃeNjbN܂BLbVÓA̒l̃Rs[[JɊi[邱ƂI / OāiʓIɂ͉炩̒ۓIȒl̓ǂݎjAl擾邽߂I / O͎s܂BLbVȎ̌́Aǂ̃f[^}X^[łAǂ̃f[^Rs[ł邩𖾊mɂ邱ƂłB}X^[Ԃ1‚łBLbVÓARs[uɃ}X^[ւ̕ύX𔽉fłȂƂƂ댯炵܂B + +\́Af[^Iɕ\邱ƂɂI / OAv[`łB́AlԂ̉“ǐ”ȂǁA̗vƋْĂ邱Ƃ悭܂B + +\́Aŏ̎2?3{ɉP邱Ƃ܂Bs߂̋Zpɂ́AlԂǂ߂̂̑ɃoCi\gp邱ƁAV{GR[hKvȂ悤ɃV{̎𑗐M邱ƁAċɒ[Ƀnt}̂悤ȂƂ܂܂܂B + +ɂ͉”\ȑ3̋Z@́AvZf[^ɋ߂Â邱ƂɂĎQƂ̋ǏP邱ƂłBƂ΁Af[^x[X炢‚̃f[^ǂݍ݁AWvȂǂ̒PȂ̂vZꍇ́Af[^x[XT[o[Ŏ擾ĂB͂ȂƂĂVXe̎ނɑ傫ˑ܂A𒲂ׂKv܂B + +Next [How to Manage Memory](09-How-to-Manage-Memory.md) \ No newline at end of file diff --git a/jp/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md b/jp/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md new file mode 100644 index 0000000..9ed4634 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -0,0 +1,15 @@ +# How to Manage Memory +[//]: # (Version:1.0.0) +́AȂgʂĂ͂ȂȂMdȃ\[XłB΂炭𖳎邱Ƃ͂ł܂AŏIIɂ̓̊Ǘ@肷Kv܂B + +P̃Tu[`͈̔͂𒴂ĎKv̈́A΂* heap allocated *ƌĂ΂܂B̃`N͖ɗȂ̂ŁAyĂȂƂ*S~*łBȂgpĂVXeɂẮA݂ɂȂĂ܂ƂɁAŖIɃ̊蓖ĂKv邩܂Bpɂ*Kx[WRN^*񋟂VXegp邱Ƃł܂BKx[WRN^̓S~ɋCÂāAvO}vANVȂɃXy[X܂BKx[WRNV͑f炵łFG[炵AR[h̊ȌƊȌ܂B”\łΎgpĂB + +AKx[WRNVłĂAׂẴS~łςɂ邱Ƃł܂BÓTIȊԈႢ́AnbVe[uLbVƂĎgpAnbVe[u̎QƂ폜邱ƂYĂ܂܂BQƂcĂ̂ŁAwΏۂ͎WłȂ̂́AɗȂB*[N*ƌĂ΂܂B[N𑁊Ɍ‚ďCKv܂BԉғĂVXeł́AeXgŃ[gʂ邱Ƃ͂܂񂪁A[U[͎gʂ܂B + +VIuWFNg̍쐬́Aǂ̃VXełKxɍłBATu[`̃[Jϐɒڊ蓖Ăꂽ́AʏAjɊȒPȂ̂ŁAłBsvȃIuWFNg̍쐬Kv܂B + +dvȃP[X́AxɕKvȃIuWFNg̏`łƂłB̃IuWFNgׂēʂ̃߂ꍇ́Aׂĕێ邽߂ɁAP̃ubN܂̓obt@蓖Ă邱Ƃł܂BKvȃIuWFNǵÃobt@Őݒ肳ꂽ]p^[Ŋ蓖Ă邱Ƃ܂BāAOobt@ƌĂ΂邱Ƃ܂B͒ʏAq[v蓖ĂłB + +Kx[WRNVɗ̂ł͂ȂA蓖ĂꂽXy[X𖾎IɉKvꍇ܂BɁA蓖Ăꂽ̊e`NɐTdȃCeWFXKpAK؂ȃ^C~OŊ蓖Ă@݌vKv܂B\bh́A쐬IuWFNg̎ނƂɈقȂꍇ܂B蓖đׂ̂Ă̎sA蓖ĉɂčŏIIɈv邱ƂmFKv܂B͔ɓ̂ŁAvO}͎QƃJEgȂǂ̊{IȌ`̃K[xWRNV邾ōς݂܂B + +Next [How to Deal with Intermittent Bugs](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/jp/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md b/jp/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md new file mode 100644 index 0000000..7f95338 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -0,0 +1,17 @@ +# How to Deal with Intermittent Bugs +[//]: # (Version:1.0.0) +fIȃoÓA50tB[g̕sŽ̓dԂOF̎ނ̃oÔƂłB͔̈ɂ܂łAώ@͓̂łA΂΂𖳎邱Ƃ͂ł܂BȂ‚邱ƂłȂ̂ŁAfobO邱Ƃ͂ł܂B + +fIȃoÓA8Ԍɂ͋^n߂܂ÂׂẴWbNƓ@ɏ]Ȃ΂Ȃ܂Bꂪ̂́Aꂪm̏ł̂݋NƂƂłBoO󋵂L^āAocL{ɉł邩𐄑ł悤ɂĂB̓f[^lɊ֘AÔ\܂BႦ΁ACI~O*lƂē͂ꍇɂ̂ݔ܂Bꂪϓ̌łȂꍇA̋^f͕ssK؂ɓKv܂B + +oO𐧌䂳ꂽ@ōČ悤ƂĂ݂ĂBČłȂꍇ́AMOVXe\z邱ƂŃgbvݒ肵܂BKvȏꍇ͓ʂȃOVXe쐬AۂɔƂɕKvƎv̂OɋL^ł܂BoOȂ̋C܂ł͂ȂAv_NVł̂݋NȂ΁A͒vZX܂BO瓾qg͉񋟂Ȃ܂񂪁AOP̂ɏ\ȏ񋟂邩܂BǂꂽMOVXéAYɓ܂łɒԂ邱Ƃ܂B̌AoOĔĂ葽̏𓾂̂҂Ȃ΂Ȃ܂B̃TCN͂΂炭̊ԑƂł܂B + +܂łɍ쐬΂fIȃoÓANXvWFNĝ߂̊֐^vO~Õ}`XbhłB͋@\vO̐mȕs]ɐTdɊmۂAgp”\ȂׂĂCPUȉꍇ8jLɊp܂BKx[WRN^̓YĂ܂BVXéAڗ‚ƂԈĂ܂OɁA΂Ύn߂dI点AԂs邱Ƃł܂B̊ԈႢɋNOɁAn[hEFAɋ^n߂ƂF߂ĒpB + +Eł͍ŋ߁AԌIȃoOATԂŌ‚܂B́AApache℁uWebT[o[̔wɂJava℁u}`XbhAvP[VT[o[Ă܂Bȃy[W^[ێ邽߂ɁA̓y[W߂XbhƂ͈قȂ4‚̕ʁX̃Xbh̏ȃZbgłׂĂI / Os܂BXÁA炩ɁA̋L^ɉԂ`邱ƂłALpȂƂ߂邱ƂɂȂ܂B4‚̃XbhĂ̂ŁA4‚ׂĂX^bNĂȂA͂ꎩ̋Ȗł͂܂łB̃XbhɂċɂꂽL[́AׂĂ̎gp”\ȃ΂₭߂āAT[o[NbV܂B̂Ƃ𗝉̂1TԂقǂ܂AA邩AXbhĂ̂͂܂܂łB + +́AT[hp[eB̃\tgEFAɊ֘A郊XNĂ܂BeLXgHTML^O폜CZXR[hgpĂ܂B̓\[XR[hĂ܂A̓T[o[̃O𗧂Ă܂ŁATdɌĂ܂łB͍ŏIIɁÂ郉CZXR[hɓdq[Xbhl܂Ă邱ƂɋCt܂B + +̃vÓAĒނ̃eLXgāA܂B͂̕ł́AR[h͓񎟓IłA肵܂B́AԂeLXg̒2ɔႷ邱ƂӖ܂B̃eLXgʓIɔĂꍇ́AɃoO𔭌͂łBނ炪܂NƂȂ΁A͌Ė܂łBꂪNƁAŏIIɖ𗝉܂łɐTԂ܂B + +Next [How to Learn Design Skills](11-How-to-Learn-Design-Skills.md) diff --git a/jp/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md b/jp/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md new file mode 100644 index 0000000..2e2fe29 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -0,0 +1,9 @@ +# How to Learn Design Skills +[//]: # (Version:1.0.0) +\tgEFA݌v@wԂɂ́A݌vɕIɑ݂邱Ƃɂă^[̍s܂B ɁA悭ꂽ\tgEFA𒲂ׂ܂B ̌AŐV̐݌vZpɊւ鏑ЂǂނƂł܂B + +ꂩAȂ͂łKv܂B ȃvWFNgn߂܂傤B ŏIIɊAfUCsAA̔zǂ̂悤ɕ򂵂lĂB ̌A̐lƋ͂āA傫ȃvWFNgɐiłB fUĆAl܂łɉN锻f̖łB X}[gȃvO}[́A2ŏ\ɊbwсAP邱Ƃł܂B + +̃X^CĴ͎RŖ𗧂܂AfUC͉Ȋwł͂Ȃ|pł邱ƂYȂłB 팱҂ɖ{ĺAȊwIɌ邱ƂɊ֐S܂B ̃fUCX^Cɂ‚ēƒfɂ͂ȂȂłB + +Next [How to Conduct Experiments](12-How-to-Conduct-Experiments.md) diff --git a/jp/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md b/jp/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md new file mode 100644 index 0000000..372fa02 --- /dev/null +++ b/jp/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -0,0 +1,23 @@ +# How to Conduct Experiments +[//]: # (Version:1.0.0) +xĈ̑Edsger DijkstráARs[^TCGX͎IȉȊwł͂Ȃ[ExpCS]łAdqvZ@ɈˑȂƂYقɐ܂Bނ͂1960N[iCt]ƌĂł܂B + +> ...@NF̃gsbŃAۂɂ͎pƂĎpȊwwԂ悤Ȃ̂łARs[eBOTCGX͐lԂ̐SɂƖߍ܂ĂA}VƂ̎Ӌ@ɂ‚āB + +vO~O͎IȉȊwłׂł͂܂񂪁AقƂǂ̍ƃvO}[́A_CNXgvZȊwɂĈӖ̂Ɋ֗^ґĂ܂B͎̕œȂ΂Ȃ܂Bw҂ׂ̂Ăł͂Ȃ悤ɁA͎̕œȂ΂Ȃ܂B30NȂɍsƂł΁A̓Rs[^TCGẌ̑ȐʂƂȂł傤B + +sKv̂̎ނ͎̂ƂłB + +- ̗ႪVXeeXgāA炪hLe[VɏĂ邱Ƃ؂AhLe[VȂꍇ̉𗝉A +- ȃR[h̕ύXeXgāAۂɃoOCǂmFA +- \̕sSȒm̂߂2‚̈قȂŃVXe̐\𑪒肷B +- f[^̐`FbNB +- ȁA܂͓oỎ铝vWB + +͂̃GbZCł͎̃fUCłƂ͎vȂBȂ͕׋AKȂ΂Ȃ܂BA2rbg̃AhoCX񋟂邱Ƃł܂B + +܂AȂ̉A܂͂ȂeXg悤ƂĂ咣ɂ‚āAɖmɂ悤ɂĂB܂AɎĂA܂͑̐lƓĂƎvꍇ́A߂̂ɖ𗧂܂B + +A̎݌vȂ΂ȂȂƂ悭܂Bꂼ͍̎Ō̎œꂽmɊÂĂ܂BāA”\Ȍ葽̏񋟂悤Ɏ݌vKv܂BcOȂA͊eȒPɂ邱ƂɋْĂ܂BoʂĂ̔f𔭓WKv܂B + +Next [Team Skills - Why Estimation is Important](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/jp/1-Beginner/README.md b/jp/1-Beginner/README.md new file mode 100644 index 0000000..d07cad2 --- /dev/null +++ b/jp/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. Beginner +[//]: # (Version:1.0.0) +- Personal Skills + - [Learn to Debug](Personal-Skills/01-Learn-To-Debug.md) + - [How to Debug by Splitting the Problem Space](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [How to Remove an Error](Personal-Skills/03-How-to-Remove-an-Error.md) + - [How to Debug Using a Log](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [How to Understand Performance Problems](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [How to Fix Performance Problems](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [How to Optimize Loops](Personal-Skills/07-How-to-Optimize-Loops.md) + - [How to Deal with I/O Expense](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [How to Manage Memory](Personal-Skills/09-How-to-Manage-Memory.md) + - [How to Deal with Intermittent Bugs](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [How to Learn Design Skills](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [How to Conduct Experiments](Personal-Skills/12-How-to-Conduct-Experiments.md) +- Team Skills + - [Why Estimation is Important](Team-Skills/01-Why-Estimation-is-Important.md) + - [How to Estimate Programming Time](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [How to Find Out Information](Team-Skills/03-How-to-Find-Out-Information.md) + - [How to Utilize People as Information Sources](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [How to Document Wisely](Team-Skills/05-How-to-Document-Wisely.md) + - [How to Work with Poor Code](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [How to Use Source Code Control](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [How to Unit Test](Team-Skills/08-How-to-Unit-Test.md) + - [Take Breaks when Stumped](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [How to Recognize When to Go Home](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [How to Deal with Difficult People](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/jp/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md b/jp/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md new file mode 100644 index 0000000..83fb792 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -0,0 +1,15 @@ +# Why Estimation is Important +[//]: # (Version:1.0.0) +ł邾p̃\tgEFAVXeғɂ́AJ̌v悾łȂAhLe[VAA}[PeBOv悷Kv܂BƃvWFNgł́A̔ƍKvłBJԂ\邱ƂłȂꍇAʓIɌv悷邱Ƃ͕s”\łB + +ǍDȐ͗\”\񋟂B}l[W[Ă܂B_IɂۓIɂA\tgEFÅJɂǂꂭ炢̎Ԃ邩𐳊mɗ\邱Ƃ͕s”\łƂ́A΂Όoc҂ɂƂĎ܂B͂̕s”\ȂƂ‚悤ɋ߂ĂAɂɒʂȂ΂Ȃ܂BA̍Ƃ̕s”\F߂ȂƂ͐łAKvɉĐĂBlɂ‚ČR~jP[V̗]n񂠂܂BlX͊킭͕͂悤ɎvX܂B + +>́A{ɖ𗝉΁A5TԂŖ50̊mŒB邱ƂłƐ܂i̊ԂɒNY܂Ȃ΁jB + +{ɈӖF + +>͍5TԌɂׂĂ̂Ƃ邱Ƃ񑩂܂B + +̈ʓIȉ߂̖ł́Aiڋqƌς肪Ӗ̂AVvĝ悤ɖIɋc_Kv܂Bނ炪Ȃɂǂ̂悤Ɍ邩ɂ炸AȂ̑OčlĂB + +Next [How to Estimate Programming Time](02-How-to-Estimate-Programming-Time.md) diff --git a/jp/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md b/jp/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md new file mode 100644 index 0000000..9637832 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -0,0 +1,21 @@ +# How to Estimate Programming Time +[//]: # (Version:1.0.0) +ςɂ͗KKvłB͂܂JKvƂB͔ɑ̘J͂̂ŁAɑ傫Ȃ̂ς悤ɋ߂ꂽꍇɂ́Aςɂ鎞Ԃς邱Ƃ߂܂B + +傫̂̌ς񋟂悤ɗ܂ꂽƂAłȂƂ̓Xg[邱ƂłBقƂǂ̃GWjA͔MIłAM]Ă܂BXg[ƁAXg[Ăs܂BAł̌ς́A炭mŐł͂܂B + +~́A^XN̎s⎎邱Ƃł܂BI͂΁A͐l𐶐łmȕ@łAۂ̐i炷B + +炩̒̂߂ɎԂƂ邱ƂłȂƂ́AŏɌς??ӖɖmɂKv܂B̈Ӗʂł̌ς??ŏƍŌ̕ɖ߂ĂBe^XN1ȉɂȂ܂ŁA^XNXɏȃTu^XNɍ\邱ƂɂāAʂɂ錩ς܂BzIɂ͒őłBłdvȂƂ͉cȂƂłBႦ΁AhLe[VAeXgAv̎ԁÃO[vƂ̃R~jP[V̎ԁAыxɎԂׂ͂ĔɏdvłBȂibNwbḧꕔ₵Ăꍇ́Â߂̍L\ςɓ܂BɂAȂ̏i͂Ȃ̎Ԃŏɗ}邱Ƃł悤ɂȂAɎԂ邱Ƃ܂B + +͈Öق̂ɐl𖄂ߍޗDꂽGWjAmĂ܂AȂƂ߂܂BpbfBǑʂ1‚́AȂ̐M͊Ô\邱ƂłBႦ΁AGWjÁA{1Ǝvd̂߂3Ԃς邩܂BGWjÁA2Ԃ𕶏A2ԑ̗LpȃvWFNgɎ|낤ƌv悵Ă邩܂BA̍Ƃ1ŊƂoî悤ɔꍇjA݂܂͉ߑ]̊Oς܂BȂۂɂĂ邱ƂK؂ɉŽ͂邩ɗDĂ܂BhLe[VR[fBO2{̎ԂvAς肪łƂ΁A}l[W[Ɍ悤ɂ邱Ƃő傫ȗ_܂B + +ɖIɃpbhBȂ̃Av[`܂ȂꍇA^XNɂ͂炭1܂A10Ă܂܂BłȂꍇ́AȂƂAm̌ςɂĕϓIɏdݕt܂BʂČς蓖Ă邱Ƃł郊XNv́AXPW[ɓKv܂B1TԂ1laCɂȂ邱Ƃ͂܂܂BÃGWjAK͂ȃvWFNgɂ͕aC܂Blɋxɂ̎ԁBāASГIȌPZ~i[`ḿHꂪłꍇ́A\܂BAm̖mA܂* unk-unks *܂B`ɂUnk-unks͌•ʂɌς邱Ƃ͂ł܂BׂĂunk-unks̃O[oȍL\쐬AiɘA鑼̕@ł肷邱Ƃł܂BAȂ̏iɔނ炪݂Ă邱ƂY邱Ƃ͂ł܂BāAunk-unkslĂȂƌς肪\ɂȂ̂́AϊȒPłB + +`[‹ł́AƂslɌς悤ɂĂB܂A`[ŜŌς??RZTX𓾂悤ƂKv܂BlX͋ZpAoAAĎM̓x傫قȂ܂B͂ȃvO}[g𐄒肵AアvO}[̐lێĂƂɂ́AJ~eB܂BŜ̃`[ςɃCƂɍӂƂśׂA`[̗𖾊mɂA\[X̐pIȍĊ蓖Ă̋@”\ɂiႦ΁Aア`[o[苭`[ɕSڂȂǁjB + +]邱ƂłȂ傫ȃXNꍇ́AȂ̃}l[W[R~bgĂȂقNj͂ɏqׁAXNƒp̂ɂȂ邱Ƃ͂Ȃ̋`łB̂悤ȏꍇɂ́AKvȂƂ΁AXN炷߂ɍs邱ƂĂ܂B + +* Extreme Programming *gp悤ɉЂɔ[邱Ƃł΁ArIȂ̂ς邾ł悭A͂ƊyYIłB + +Next [How to Find Out Information](03-How-to-Find-Out-Information.md) diff --git a/jp/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md b/jp/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md new file mode 100644 index 0000000..b072fcb --- /dev/null +++ b/jp/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -0,0 +1,19 @@ +# How to Find Out Information +[//]: # (Version:1.0.0) +ȂmKv̂鐫́AȂ‚@肵܂B + +\tgEFAi̍ŐṼpb`xȂǁAqϓIŊȒPȋ̓IȂ̂Ɋւ*Kvȏꍇ́AC^[lbgAfBXJbVO[vɓe肵āA̐lɒJɎ₵ĂBC^[lbgňӌϓIȉ߂̂ꂩ@Ă̂͌ȂłBhuƐ^̔䗦܂B + +ȂϓIȂ̂ɊւʓIȒm*lXɂ‚člĂjm肽ȂA}فi{ۊǂĂ镨Ijɍs܂BƂ΁Aw₫̂_ɂ‚ĊwԂɂ́A}قɍs܂B + +ȂmĂKv*ȒPȂƂł͂Ȃ@* 2‚܂3‚̏Ђ擾AǂłBȂ́AC^[lbg\tgEFApbP[WCXg[ȂǁAȒPȂƂ@wԂ܂BǂvO~OeNjbN̂悤ȏdvȂƂwԂƂł܂A\bhubN̓K؂ȕǂނ̂ɗvʂ̌ƕבւAʂ̌̌@oɂƑ̎Ԃ₷Ƃł܂B + +*ɒNm肽Ȃ񂪕Kvȏꍇ*Ƃ΁Ã\tgEFAȃf[^Zbg̐Vił邱ƂmĂꍇAC^[lbgƃCuKv܂B̃IvVSɎgsꂽAmF邽߂Ɏ݌v邱Ƃł܂B + +Ɠȏ󋵂lӌ≿lfKvȏꍇ́AƂɑkĂBƂ΁ALISPɍŐṼf[^x[XǗVXe\z邱Ƃǂǂm肽ꍇ́ALISP̐Ƃƃf[^x[X̐ƂɑkKv܂B + +*܂JĂȂ̃AvP[Vp̂荂ȃASY݂”\邱Ƃm肽ꍇ́ÃtB[hœĂlƘb܂傤B + +ȂrWlXn߂Ȃ΂ȂȂǂȂl邱Ƃł悤*lIȌ̂ł΁ÃACfBAɑ΂c_̃XgĂ݂ĂBꂪs΁A肢lĂBׂĂ̊pxACfAwсAȂ̏hׂďIāAȂ̐S̒łׂĂ̌ʂƒƒZ菜AˑRƂĞBȂ܂܂łƂ܂BȂ͍Ȃ̐Sɏ]āAȂ̔]ɖق悤ɌȂ΂Ȃ܂Bp”\Ȑ肢̋Z@̑́AȂ݈̐ӎӖ蓖Ă銮SȂ܂Ń_ȃp^[񎦂̂ŁA̔ӎIȗ~]𔻒f̂ɔɖ𗧂܂B + +Next [How to Utilize People as Information Sources](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/jp/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md b/jp/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md new file mode 100644 index 0000000..a4b6254 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -0,0 +1,15 @@ +# How to Utilize People as Information Sources +[//]: # (Version:1.0.0) +ׂĂ̐l̎Ԃ𑸏dA̎ԂƃoXĂBNɎ₷邱Ƃ́A󂯎邾ł͂܂B̐l͂Ȃ݂̑yŁA̎𕷂ƂɂāAȂɂ‚Ċwт܂B̐lɂ‚ē悤ɊwсAȂ߂铚m邱Ƃł܂B́AȂ̎͂邩ɏdvłB + +Ảl͂Ȃsقnj܂BȂ́Aǂ̂ƂAlĂłMdȏiAȂ킿̎ԂgĂ܂BR~jP[V̗_́ARXgƔrďdKv܂BɁÃRXgƗ_́AlɂĈقȂ܂B́A100l̊5̑gD̊elƘbKvƋMĂA̎Ԃ̖5ɂȂ܂BA1000l̏]ƈꍇA10”\A5”\܂BgD̊elƘbԂ́A̖iEʈȏjɂĈقȂ܂BȂ̏iɏiƘbׂłAȉiɏbĂB͕s܂񂪁A͂ȂiɏAAbĂ`ƐMĂ܂B + +{Iȃ[́ANȂƘbƂ痘v𓾂邱ƂłAނ炪ȂɘbƂقǁAނ炪h闘v͏ȂƂƂłBނɂ̉b񋟂AނƂ̃R~jP[V̗v𓾂邽߂ɁAȂ̎d́A₳ꂽԂƂ̃oXŗvۂ‚ƂłB + +̎Ԃ𑸏d邱ƂdvłBNƘbȂAƂɎԂƂĂAԂ啝ɐߖ񂷂ł傤BȂ̎ԂȂ̂̂MdȂ̂ƎvȂAsׂłB + +̊ȗ͉ẴC^[łBxɋZpIȗ̉ĊC^[́A܂萬ʂグ邱Ƃ͊҂ł܂Bނ͂ɂNnɏP邱Ƃ\z܂BłȂ͗eF܂Hꂵ񂾐ĺAC^[dvȉ󂯂Ă̂ŁBނ͏֎@𓾂B炭AVACfA𕷂`X܂Bނ͈قȂ鎋_畨@𓾂Bނ͂܂AC^[W悤ƂĂ邩܂񂪁AłȂꍇłAׂƂ񂠂܂B + +Ȃ́AɌƂƐMƂ͂‚łAlXɔނ̒mbƔf͂̂ق̏q˂ׂłB͔ނ𕽂炰AȂ͉wсAł傤BǂvO}[́AZ[XSoCXvWfg̏KvƂȂƂ͂悭܂A܂łɍsƂ΁A߂ĂB͉cƒS҂̎d悭邽߂ɁA‚̃Z[XR[𕷂Ă݂邱Ƃx߂܂B30v܂łA͏K͂ȓw͂̔Ɉۂ^Ǝv܂B + +Next [How to Document Wisely](05-How-to-Document-Wisely.md) \ No newline at end of file diff --git a/jp/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md b/jp/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md new file mode 100644 index 0000000..39f36ae --- /dev/null +++ b/jp/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -0,0 +1,20 @@ +# How to Document Wisely +[//]: # (Version:1.0.0) +l͒ZĒNǂ܂Ȃ炢̂ƂĂBȂ킲ƂȂANǂ܂Ȃł傤BāAǂhLgœKłB}l[W[͂𗝉ĂȂƂ悭܂BȂȂAhLe[VłĂAނ炪vO}[ɈˑĂȂƂZLeBo^邩łBN{ɖɗȂĂƒfĂꍇ́Au͂vƌĐÂɎdTn߂B + +hLg̎vɘa邽߂ɁAK؂ȃhLgςɑgݍނ̂ɂ鎞Ԃ𐳊mɌς邱Ƃ́AقnjʓIł͂܂B^͊ēFeXĝ悤ȃhLǵAR[hJ{邱Ƃ܂B + +ǂƂ́A܂ɁAǂłB͂ȂMA׋AKɊւ{‚邱Ƃ߂܂BAƂȂڗȍƂłĂAȂȂ΂ȂȂt̕nȖ߂ĂĂÃ[͖{ɕKvȂ̂łFuȂނɂȂ̂Ƃ悤ɁAlɍs܂BNȂ̏ނǂł̂A甲oKv̂??Aǂ̂悤ɂ邱Ƃł̂lĂBȂAȂ͕ϓIȃhLe[VC^[łAǂvO}[ɂȂł傤B + +vO}[ȊO̐lۂɓǂނƂł镶쐬̂ł͂ȂAۂɃR[ĥ𕶏邱ƂɊւẮA܂łɒmĂō̃vO}[͕ՓIȊĂ܂F̃R[hāAR[ĥƂł͂肳邱Ƃ͂ł܂Bɂ́A2‚̗R܂B܂AR[hx̃hLgQƂKvĺAقƂǂ̏ꍇAR[hǂ߂悤ɂȂ܂BmɁA͏S҂oLxȃvO}[ɂƂĂ͊ȒPłBAɏdvȂ̂́AȂ΁AR[hƕ͖ĂȂƂƂłBň̏ꍇA\[XR[h͊Ԉč”\܂BSɏĂȂ΁A͂̕‚ƂłA͉{܂B + +͐ӔCvO}[ɂƂĂȒPɂ͂Ȃ܂B̃R[hǂ̂悤ɏ̂łH͂ǂӖłḦӖ́F + +NǂޕKv邱ƂmĂR[hB +- S[f[KpB +- ʂ̃\[VvɗpłꍇłAȒPȃ\[VIB +- R[hlj鏬ȍœK]ɂB +- ǎ҂̂ƂlāAޏƊyɂMdȎԂ₵ĂB +- `foo`A` bar`A `doIt`̂悤Ȋ֐gp邱Ƃ͂܂I + +Next [How to Work with Poor Code](06-How-to-Work-with-Poor-Code.md) \ No newline at end of file diff --git a/jp/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md b/jp/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md new file mode 100644 index 0000000..47e313b --- /dev/null +++ b/jp/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -0,0 +1,10 @@ +# How to Work with Poor Code +[//]: # (Version:1.0.0) +N򈫂ȃR[hōƂȂ΂ȂȂƂ͔ɈʓIłBAȂC𗚂܂ł́A܂ɂnł͂ȂƎvĂBނ́AXPW[͂𖞂߂ɉ΂₭s߂ɁAӎIɗ܂Ă邩܂Bɂ炸AsĂȃR[hōƂɂ́A𗝉Kv܂B𗝉ɂ͊wKԂKvŁA̎Ԃ͂ǂ̃XPW[oȂ΂Ȃ炸AȂ͂咣Kv܂B𗝉ɂ́A\[XR[hǂ܂Ȃ΂Ȃ܂BȂ͂炭Kv܂B + +R[h𕶏悤ƂƁAȂlȂȂpxlȂ΂ȂȂȂAʂƂē镶𗧂‚Ȃ̂ŁAgłĂA𕶏̂͂ԂłBĂԁAR[ḧꕔ܂͑Sɂ͉KvlĂB͎ۂɂ鎞Ԃߖ񂷂ł傤HȂƁAȂ͂Młł傤HŘɒӂĂBȂƁAȂ͑Ώ₷Ȃ܂Aǂ܂Ȃ΂ȂȂ̐lɂƂĂ͖{ɊȒPł傤HȂȂAeXg̕S͂łHăeXgKv́A”\̂闘vdv낤H + +ȂĂȂR[hɑ΂Ƃ̂߂̂Ȃ̐ł́ÃR[h̕íAunk-unks̃XNɑ΂邠Ȃ̔Fɉe^͂łB + +vO}̍łDꂽc[̂2‚ł钊ۉƃJvŹAɖȃR[hɓKp”\ł邱ƂoĂƂdvłB傫ȃR[hubNĐ݌v邱Ƃ͂łȂ܂񂪁A钊ۉʂlj邱Ƃł΁AǂfUC̃bg𓾂邱Ƃł܂BɁA•ʂɍĐ݌v邱Ƃł悤ɁAɈi菜Ƃł܂B +Next [How to Use Source Code Control](07-How-to-Use-Source-Code-Control.md) \ No newline at end of file diff --git a/jp/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md b/jp/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md new file mode 100644 index 0000000..275f197 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -0,0 +1,9 @@ +# How to Use Source Code Control +[//]: # (Version:1.0.0) +\[XR[hǗVXeio[WǗVXeƂĂ΂܂jł́AvWFNgʓIɊǗł܂Bނ͈lɂƂĂƂĂLpŁAO[vɂ͕KvsŒłBR[hꂸAύXɈӖ蓖Ă邱Ƃł悤ɁAقȂo[ŴׂĂ̕ύXǐՂ܂BȂύXR[h́A`[ƋLA܂̓[XR~bgꂽ̃R[hTdɕۂ̂ŁA\[XR[hǗVXeɎMăX[AEFCƃfobOR[h쐬邱Ƃł܂B + +̓\[XR[hǗVXe̗_𗝉̂ɒx܂A1l̃vWFNgłȂĂĂ܂BʓIɂ́AR[hx[XōƂ`[KvȏꍇɕKvłBAނɂ͕ʂ̑傫ȗ_܂BR[h𐬒ĂI[KjbNVXeƍl邱Ƃサ܂BeύX͐VO܂͔ԍ̐VrWƂă}[N邽߁A\tgEFA͖ڂɌiIȈẢPƍl悤ɂȂ܂B͂ꂪS҂ɂƂēɕ֗Ǝv܂B + +\[XR[hǗVXegp邽߂̗ǂeNjbŃAɍŐV̏ԂɂȂĂ琔ȓɑ؍݂邱ƂłBŏIłȂR[h̓`FbNCĂ܂AANeBuŌĂяo邱Ƃ͂Ȃ߁A̐lɂ͖͐܂BȂ̃`[CgԈႢƂƂ͏dȃG[łB͂΂΃^u[łB + +Next [How to Unit Test](08-How-to-Unit-Test.md) diff --git a/jp/1-Beginner/Team-Skills/08-How-to-Unit-Test.md b/jp/1-Beginner/Team-Skills/08-How-to-Unit-Test.md new file mode 100644 index 0000000..4c11c57 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -0,0 +1,9 @@ +# How to Unit Test +[//]: # (Version:1.0.0) +P̃eXǵA`[ɂăR[hꂽ@\̌X̕eXg邱Ƃ́AƂ͈قȂ̂ł͂ȂAR[fBÖꕔłB R[h̐݌v̈ꕔ́AeXg@݌v邱ƂłB 1‚̕łĂAeXgv߂ׂłB ɂ̓eXgȒPɂȂFu{^͌hǂ́Hv ɂ͕GɂȂ܂F '̃}b`OASY͐mɐ}b`Ԃ܂H' + +”\ł΁AAT[V`FbNƃeXghCogpĂB ͑ɃoOLb`邾łȂAŔɕ֗ŁAȂSzKv̂Ȃ~Xe[r܂B + +GNXg[EvO~O̊J҂́AjbgEeXgʓIɎsĂ܂B ͔ނ͂̕𐄑E܂Ƃ͂ł܂B + +Next [Take Breaks when Stumped](09-Take-Breaks-when-Stumped.md) \ No newline at end of file diff --git a/jp/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md b/jp/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md new file mode 100644 index 0000000..bc49204 --- /dev/null +++ b/jp/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -0,0 +1,5 @@ +# Take Breaks when Stumped +[//]: # (Version:1.0.0) +Ƃ́AxeĂB ƂɎ͎ɂ15ґzAɖ߂Ƃɖ͖@̂悤ɉB ͎̐ɂ͓悤ɑ傫ȂB ꎞIɑ̃ANeBreBɐ؂ւ邱Ƃł܂B + +Next [How to Recognize When to Go Home](10-How-to-Recognize-When-to-Go-Home.md) \ No newline at end of file diff --git a/jp/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md b/jp/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md new file mode 100644 index 0000000..5f8fbfe --- /dev/null +++ b/jp/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -0,0 +1,16 @@ +# How to Recognize When to Go Home +[//]: # (Version:1.0.0) +Rs[^vO~ÓAł銈łBcOȂƂɁASǧN؂ɂ镶ł͂܂BI/jIȗRiႦ΁AԂɃRs[^A[hKvjAs꓊܂ł̎Ԃ̈ƃvO}̕ŝ߂ɁARs[^vO}͓`IɉߘJłB͂ȂĂ邷ׂĂ̕M邱Ƃ͂łȂƎvĂ܂AT60ԂʓIŁA50͂Ȃ菭ȂƎv܂B́A͂邩ɑ̂ƂKvł邱ƂӖ܂B͗ǂvO}ɂƂďdȖłAvO}͎gł͂Ȃ`[Cgł܂B‰ƂɋAׂAɂ͑̐lƂɋA邱ƂƂFKv܂B̖邽߂̌Œ肳ꂽ[͂܂BȂȂ瓯RŁAׂĂ̐lԂقȂĂ邩łB + +1TԂ60Ԃ𒴂ƁA͒Zԁi1Tԁj\ނƂłAɂ͎Ɋ҂AɂƂēʂȓw͂łB͐l60Ԃ̎d҂̂ł邩ǂ͕܂B40ł邩ǂ킩ȂBA͂ȂĂ]ȎԂłgʂĂقǁAdłƊmMĂ܂BlIɂ́A͏T60ԈȏłB͌lIɂ́AvO}[m[uXsďdS𕉂Ȃ΂ȂȂƍlĂ܂BA̓vO}̋`ł͂܂B߂́AvO}[́AN̂߂ɃV[邽߂ɁAႦΌoc҂ɈۂÂ}l[W[ȂǁApgCɂȂ邱Ƃ悭v܂BvO}[͂΂΂ɋꂵł܂BȂȂAނ͊ŗ~ƔM]ĂāAł͂ȂƌĂȂłBɑ΂4‚̖h䂪܂F + +- Г̑SƂȂׂ̐lƃR~jP[VƂāANĂ̂ɂ‚Čoc҂Ɍ^邱ƂȂ悤ɂ܂B +- hqI–IɌςAXPW[𗧂Ă邱ƂwсANXPW[ł邩AǂɗĂ̂悤ɂB +- Kvł΂A`[ƌƂw +ȂKvΏI܂B + +قƂǂ̃vO}[͗ǂvO}[łAǂvO}[͑̂ƂƎvĂ܂B̂߂ɂ́AԂʓIɊǗKv܂BɒgȂAɐ[ւ邱ƂɊ֘AāAx̐_I܂B̃vO}[́AEH[~OAbvďW鎞Ԃēr؂邱Ƃ̂ȂԂ΁Aނ炪łʓIłƊĂ܂BAlX͖Ȃ΂Ȃ炸A̔C𐋍sȂ΂ȂȂBꂼ̐ĺAlԂ̃YƎd̃Y̗𖞑@‚Kv܂BevO}[́Ałdvȉcɂ̂ݎQ̓\񂷂ȂǁAIȍƊԂmۂ邽߂ɕKvȍƂׂčsKv܂B + +͎q̂ŁAXނƈꏏɖ߂Ă܂BɂƂčłʓIȃÝAɒ߂ƂłBItBXItBX߂ŐQ邱Ƃł܂i͒ʋ΂ʋ΂܂Œʋ΂Ă܂jBQB͂ɊĂ܂񂪁A͎łőP̑ËĂłB`ȁꍇ͉ƂɋABȂEvllĂȂAȂ͉ƂɋAׂłBEl̎vl𐔕bȏlƁAxeƂɋAׂłBdx̐_ُAyx̂•aȊO̐_̒ꍇ́ANƂɔhĂBȂʏ͔̌ł͂Ȃ@ŕs܂͋\ԂɗUfꂽꍇ́AxeKv܂BJɑ΍R邽߂ɃRJC܂̓AtF^~gpȂłBJtFC𗐗pȂłB + +Next [How to Deal with Difficult People](11-How-to-Deal-with-Difficult-People.md) diff --git a/jp/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md b/jp/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md new file mode 100644 index 0000000..4bf81ab --- /dev/null +++ b/jp/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -0,0 +1,15 @@ +# How to Deal with Difficult People +[//]: # (Version:1.0.0) +炭AlɑΏȂ΂ȂȂł傤BȂgl܂BȂ⌠Ў҂Ƒ̊Ă悤Ȑl̏ꍇ́AꂪӖƗ؂ɂȂ΂Ȃ܂񂪁AȂ̒m⌴]ɂ邱ƂȂA + +́Â悤ȂƂoĂ炸AȑO̐loEŖɗȂsp^[ĂꂽvO}[ɂƂẮAɎזɂȂ邱Ƃ܂Bl͂΂Έӌ̕svɊĂA҂ËЉI͂̉e󂯂ɂB͓K؂ɑd邱ƂłB́AȂ]ނ͂邩ɑAނ炪]ނقǑ͂܂B + +vO}[̓`[ƂĈꏏɓȂ΂Ȃ܂BsvƂA͉ƂȂ΂ȂȂA͒ԋ肷邱ƂłȂBl͂΂ΔɌŁAɗLpȂƂ܂Bl̐lɂĈNΌȂė邱ƂdvłBR~jP[V̎śA΂Εsv̍łAɂ͑傫ȔEςŎ菜Ƃł܂B̃R~jP[VŜ̂ɕۂA傫ȑN”\̂a󂯓ȂłB悤Ƃ鍇IȊԂ̌AB + +߂qȂɓӂȂ悤ɋȂłBȂ[_[ł΁AȂԗǂƎvƂĂBlIȗRŌfȂŁA藝R鏀ĂBlƃ`[CgĂꍇ́A[_[̌ɌlIȉe^ȂłBꂪȂ̓sƂȂȂ΁A͂܂S߂đ̂łB + +l͕ωAPB͎̖ڂł܂A͔ɂ܂łBANꎞIȕ݂܂B + +ׂẴvO}[AɎw҂ʂĂۑ1‚́AȐlSɏ]邱ƂłBނ͎dAqɂXÂ̂󓮓IɒRX܂B. + +Next [Intermediate skills](../../2-Intermediate) diff --git a/jp/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md b/jp/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md new file mode 100644 index 0000000..e218b32 --- /dev/null +++ b/jp/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -0,0 +1,13 @@ +# How to Tradeoff Quality Against Development Time +[//]: # (Version:1.0.0) +\tgEFAJ́AvWFNgsƂƃvWFNg邱Ƃ̊ԂŏɑËłBAGWjAOrWlX̊‚悤ȕ@ŃvWFNg̓WJXs[hAbv邽߂ɁAig[hIt悤ɋ߂邱Ƃ܂BƂ΁A\tgEFAGWjAO̊snŁAeiX̖肪悤ȍƂ悤ɋ߂ꍇ܂B + +ꂪNꍇ́A܂`[ɒm点Aiቺ̃RXg𖾊mɐ邱ƂłBǂ̂ƂAȂ̗͂Ȃ̏i̗͂邩ɗǂ͂łBĂ̂AĂ̂𖾊mɂÃTCNŎꂽnʂǂ̂悤ȃRXgŎ߂̂ł傤B̒ŁAǂvWFNgv悪񋟂Ž𗧂‚͂łBĩg[hItiۏ؂̓w͂ɉeyڂꍇ́AwEĂiiƕiۏؒS҂̗ɁjBĩg[hItiۏ؊Ԍɕ񍐂oO𑝂₷ꍇ́AwEĂB + +ޏ܂咣ĂȂÃTCNŏPv悷邱Ƃł̃R|[lgɕsR𕪗悤ƂׂłBȂ̃`[ɐAv𗧂Ă邱Ƃł܂B + +SlashdotNinjaProgrammer̕΂𑗂F + +>Dꂽ݌v́AnȃR[hɑ΂ĉ񕜂邱ƂYȂłBR[hŜŗǍDȃC^tF[XƒۊTO݂ꍇAŏIIȏ͂͂邩ɖɂɂȂ܂BCmȃR[ĥꍇ́ANĂRAfUCɉȂ̂ĂB + +Next [How to Manage Software Dependence](02-How-to-Manage-Software-System-Dependence.md) diff --git a/jp/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md b/jp/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md new file mode 100644 index 0000000..c3ab39a --- /dev/null +++ b/jp/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -0,0 +1,13 @@ +# How to Manage Software System Dependence +[//]: # (Version:1.0.0) +̃\tgEFAVXéAȂ̃Rg[ɒڑ݂ȂȂ̃R|[lgɈˑX܂BɂAViW[ƍėpɂ萶Yサ܂BAeR|[lgɂ͂‚̖肪܂B + +- R|[lg̃oOǂ̂悤ɏC܂H +- R|[lg̃n[hEFA܂̓\tgEFAVXeɐĂ܂H +- R|[lgSɎsǂ܂H + +R|[lg炩̕@ŃJvZAR|[lgAXbvAEgł悤ɂ邱ƂɃxXgłBR|[lgSɋ@\ȂƔꍇ́Aʂ̃R|[lgɓ邱Ƃł܂AƎ̃R|[lg쐬Kv܂BJvZ͈ڐAł͂܂񂪁AڐAeՂɂȂ܂A͂قړłB + +R|[lg̃\[XR[h‚Ƃ́AXN4{Ɍ܂B\[XR[hgpƁAȒPɕ]AȒPɃfobOA‚₷ȂACȒPɍsƂł܂BCvO쐬ꍇ́AR|[lg̏L҂ɏCvOnACvO[XɑgݍޕKv܂BȊȌꍇ́Ão[WێKv܂B + +Next [How to Decide if Software is Too Immature](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/jp/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md b/jp/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md new file mode 100644 index 0000000..59629bb --- /dev/null +++ b/jp/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -0,0 +1,18 @@ +# How to Decide if Software is Too Immature +[//]: # (Version:1.0.0) +̐l\tgEFAgp邱Ƃ́ASȃVXevɍ\złʓIȕ@1‚łB͗_ׂł͂܂񂪁AɔXNȂ΂Ȃ܂Bł傫ȃXN1‚́A\tgEFAgp”\ȐiɐnOɁA΂΃\tgEFAɊ֘AĂAoOƕsSȓ̊ԂłB\tgEFAVXeƂ̓OɁAГō쐬ꂽ̂ł낤ƑO҂ɂč쐬ꂽ̂ł낤ƁAۂɎgpɂ͏\ɐnĂ邩ǂ邱ƂɏdvłBłȂgɐq˂ׂ10̎₪܂F + +1.CłH i񑩂͔ɖnłjB +2.\tgEFAɊւm̂ANZX”\Ȗ{̂܂H +3.Ȃ͍ŏ̃[U[łH +4.pɋCZeBu͂܂H +5.eiXɓw͂Ă܂H +6.݂͌̃ei̕󂩂琶c邱Ƃł܂H +7.ȂƂ̖t̑֕i܂H +Ȃ̕Ђɂ͒mĂ܂H +Ȃ̕Ђɂ͖]܂̂łH +10.ȂꍇłɎgސlXقƂł܂H + +̊l΁ANƉƂ̃XN팸邽߂̏\Ɋmꂽt[\tgEFAƃI[v\[X\tgEFȂ傫ȉlؖ܂B + +Next [How to Make a Buy vs. Build Decision](04-How-to-Make-a-Buy-vs-Build-Decision.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md b/jp/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md new file mode 100644 index 0000000..f6d15bc --- /dev/null +++ b/jp/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -0,0 +1,16 @@ +# How to Make a Buy vs. Build Decision +[//]: # (Version:1.0.0) +\tgEFAgĉB悤ƂĂNƉƂ̊ƂvWFNǵAɁuwv΁uv̌Ȃ΂Ȃ܂B̃t[Ỹ^[́A2‚̓_ŕsKłBI[v\[XƁAK*ĂȂt[\tgEFA𖳎Ă悤BɏdvȂ̂́ARXglKv邽߁AŎ擾ē邩Aō\zČ肷邩𓝍邱ƂłBɂ́ArWlXAǗAGWjAOɐʂlނKvłB + +- Ȃ̃j[ÝAꂪ݌vꂽ̂Ƃǂꂭ炢悭Ă܂H +- Ȃŵ̂Aǂ̕KvłH +- ]RXg͂łH +- ̃RXg͂łH +- w͒IȈێ𑝌邾낤H +- \z邱ƂŁAȂ]łȂrWlX|WVɂȂuƂ͂ł܂H + +Ȃ́ÃrWlXŜ̊bƂȂقǑ傫Ȃ̂\zOɁAxlȂ΂Ȃ܂B̂悤ȃACfÁAȂ̃`[ɍv邱Ƃ񂠂閾邭yϓIȐlXɂĒĂ邱Ƃ悭܂Bނ̃ACfA͓Ił΁ArWlXvύX܂BӎȂẴrWlX傫ȃ\[VɓȂłB + +̎A炭zpƍwp2‚̃vWFNgvĂKv܂BɂARXglKv܂B܂Ã\[V̒IȃeiXRXglKv܂BRXgςɂ́A\tgEFAwOɊSȕ]sKv܂BȂ]邱ƂłȂꍇAȂ͂wۂɕsȃXNz肵A̓̐iw邱Ƃ肷Kv܂Bl̍w肪‚ꍇAꂼ]邽߂ɂ‚̃GlM[₷Kv܂B + +Next [How to Grow Professionally](05-How-to-Grow-Professionally.md) diff --git a/jp/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md b/jp/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md new file mode 100644 index 0000000..a221e2a --- /dev/null +++ b/jp/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -0,0 +1,11 @@ +# How to Grow Professionally +[//]: # (Version:1.0.0) +Ȃ̌𒴂ӔC𕉂܂B Ȃ]ޖʂĂB K͂ȑgD̐ւ̐lX̍vAĂȂlIɖ𗧂‚̂ւ̊ӂ\ĂB + +Ȃ`[[_[ɂȂ肽ȂARZTX̌`𑣂B }l[W[ɂȂ肽ꍇ́AXPW[SĂB [_[}l[W[ƈꏏɎdĂԂ́Aʏ킱KɍsƂł܂BɂA[_[}l[W[傫ȐӔC𕉂ƂɂȂ܂B ꂪȂAxɏĂB + +Ȃg]ĂB ȂǂvO}ɂȂ肽ȂAȂǂ̂悤ɂ̂悤ɂȂ邱Ƃł邩܎^lɐq˂ȂB iɕƂł܂Biɂ͒mĂ܂AȂ̃LAɑ傫ȉe^܂B + +V\tgEFAVXewԂƂ̂悤ȁAׂȋZpIȂ̂łAȂ̎dɂ𓝍邱ƂɂāA܂悤ȃn[hȎЉIȂ̂łAVXLwԕ@v悷B + +Next [How to Evaluate Interviewees](06-How-to-Evaluate-Interviewees.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md b/jp/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md new file mode 100644 index 0000000..eda4420 --- /dev/null +++ b/jp/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -0,0 +1,15 @@ +# How to Evaluate Interviewees +[//]: # (Version:1.0.0) +ݓIȏ]ƈ]邱Ƃ́Aɂӂ킵GlM[^ĂȂB̂悤Ȉٗp͂ЂǂłB݂Ȃ̃GlM[̂Ȃ͕̕Wɔ₳ׂłA͂߂ɍs܂B + +C^r[X^C͂܂܂łB҂̒ɂ͔ɃXgX悤ɐ݌vꂽƂ܂B̓XgXł̃LN^[ׂ̌_𖾂炩ɂɋMdȖړIʂ܂B҂͎gƔׂăC^rA[ɂ͐ł͂ȂAȋ\Ԃɑ΂lԂ̔\ׂ͂͋̂łB + +Ȃ͏ȂƂA2Ԃ̋ZpXĽɑ̂҂ɗ^ׂłBKł́AmĂ邱Ƃ΂₭Jo[AE}[N邽߂ɒmȂ̂炷΂₭߂Ƃł܂Bʐڎ҂͂𑸏dł傤B́AC^r[ŁA̎͊ƂIԓ@1‚łƐ񕷂Ƃ܂BPǂȐĺAނ炪Ōɓꏊނ炪swZA܂͑̕sŒȓł͂ȂAނ̃XL̂߂ɌقꂽƎvĂ܂B + +sɂẮAmĂ͂邩ɏdvȁAwK\͂]Kv܂B܂AȐlɂĕꂽLQ̗~ĎKv܂BȂ̓C^r[̌Ńm[gr邱ƂɂĂF邱Ƃł邩܂񂪁AC^r[̔MłF邱Ƃ͍łBŐṼvO~OAlXR~jP[VĐlXƂǂ̂炢܂ĂdvłB + +ǎ҂̓C^r[Ώێ҂̂߂ɃeCNEz[EeXggčK^FĂ܂B́Ag܂񎦂邱Ƃł܂Aۂɂ̓R[h邱ƂłȂC^rC[𖾂炩ɂ邱ƂłƂ_܂B͌lIɂ͂̃eNjbNĂ܂񂪁A͌Ȃ悤łB + +ŌɁAC^r[͔̔̃vZXł܂B҂ɂȂ̉ЂvWFNg𔄂Ă͂łBAȂ̓vO}ƘbĂ̂ŁA^FÂ悤ƂȂłB̂n߂āAɗǂ̂ŋdグĂB + +Next [How to Know When to Apply Fancy Computer Science](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/jp/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md b/jp/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md new file mode 100644 index 0000000..a2d6378 --- /dev/null +++ b/jp/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -0,0 +1,15 @@ +# How to Know When to Apply Fancy Computer Science +[//]: # (Version:1.0.0) +ASYAf[^\AwȂ̂قƂǂ̃vO}mĂ邱Ƃ͂قƂǂ܂񂪁A܂gĂȂƂɂ‚Ă̒m܂Bۂɂ́Ȃf炵̂͂܂ɂGňʓIɂ͕svłBقƂǂ̎ԂIȃf[^x[XĂяoŝɔ₳ꂽƂɂ́AASỶPɂ͉̈Ӗ܂BvO~O̕sKȗʂ́AVXe݂ɘbAɒPȃf[^\gĂ΂炵[U[C^[tFCX\z邱Ƃ琬܂B + +xȋZp͂“K؂ȋZpłHȂ́A{̃ASYȊỎ𓾂邽߂ɂ–{ǂׂłHŝ֗ȂƂ܂ATdɕ]Kv܂B + +ݓIȃRs[^TCGXZp3‚̍łdvȍl͎̂ƂłB + +- ̃VXeɑ΂郊XNႭAGƕێRXg̑S̓IȑȂ悤ɁA\ɃJvZĂ܂H +- v͋ٓIłiႦ΁AnVXeł2{AVVXeł10{jB +- ʓIɃeXg]邱Ƃł܂H + +킸ɕGȃASYgpǗASYł́AVXeŜŃn[hEFÃRXg팸AptH[}X2{ɍ߂邱Ƃł΁Aƍߎ҂͂lȂƂɂȂ܂B̂悤ȃAv[`咣錮1‚́AĂꂽZp炭\ɌĂ̂ŁAXNۂɂ͂ȂႢƂƂłBB̖͓̃XNłBŃvO}̌oƔf́AeՂɂ邽߂̔hȋZpƑʂ܂B + +Next [How to Talk to Non-Engineers](08-How-to-Talk-to-Non-Engineers.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md b/jp/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md new file mode 100644 index 0000000..54921d7 --- /dev/null +++ b/jp/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -0,0 +1,19 @@ +# How to Talk to Non-Engineers +[//]: # (Version:1.0.0) +ɃGWjAvO}[́AʓIȕɂāA̐lXƂ͈قȂƈʂɔF߂Ă܂B́A̐lXƈقȂ邱ƂӖ܂B́AGWjAȊO̐lƃR~jP[VƂƂɂ͗ӂ鉿l܂BȂ͏Ɋϋq𗝉Kv܂B + +mGWjA̓X}[głÂ悤ɋZpIȂƂ쐬邱Ƃɍ̂ł͂܂B͕Bނ͕𔄂AA𐔂Ǘ肵܂AƂł͂܂BGWjÂ悤Ƀ`[ňꏏɎd̂͂܂ǂ܂iO͂܂jBނ̃\[VXL͈ʂɁA`[ȊO̊‹̃GWjAƓȏłAeȁAmȃR~jP[V̎ނƎsd̐TdȍוB + +GWjAȊO̐l͂܂ɂł邩܂񂵁AȂɋ邩܂BƓ悤ɁAނ͖{ɂȂ΂邱ƂӖ̂łAȂ̂Ƃ|Ă̂ł͂ȂAt̔wɗ‚Ƃ܂B + +vO}[ȊO̐l͋ZpIȂƂ𗝉邱Ƃł܂AZpIȔfłɂƂĂƂ͂܂Bނ̓eNmW[̎dg݂𗝉Ă܂AȂ̃Av[`3̂AĂ1‚3̂ł܂B iǂ̂ƂAvO}[͂̎̌ςɂٓIȂƂ܂Bj́AƑʂ𔭊D̋@łB + +Ȃ̃`[ƘbƂɂ́AvlɁAʓIȋZpɂȂ̐iɊւ鑽̌oL邽߁AZkꂽtgpČʓIłB̑LAɂȂg̃`[̃o[ƂɁǍoLĂȂlɂ͎gpȂ悤ɂɂ́A̓w͂KvłB̃{Lu[́AȂƂLȂlƂ̊ԂɕǂAɈƂɁA̎Ԃ𖳑ʂɂ܂B + +`[ł́A{IȑOƖڕWpɂɍċLqKv͂ȂAقƂǂ̉b͏ڍׂɏœ_𓖂ĂĂ܂BO҂̏ꍇA͋tɂȂ܂Bނ͂ȂR̂Ƃ𗝉ĂȂ܂BȂ͂𓖑R󂯎AJԂȂ̂ŁA{ɑ傫ȌƂɂ݂𗝉ƂO҂̍lāAbcƂł܂BȂ́ǍR~jP[V‚邽߂ɁAR~jP[VĐTdɌĂƑz肵ĂBȂĂ邱ƂmF邽߂ɂȂĂ邱Ƃv񂵂茾肷悤ɂĂBpɂɉ@ꍇ́AʓIɃR~jP[VĂ邩ǂq˂鎞Ԃ₵ĂBR~jP[Vɖ肪ꍇ́ÅsςĂAɕs点ĂB + +͔GWjAƂ̎dDłB͊wсA傫ȋ@񋟂܂BȂ́AR~jP[V̖m̊ϓ_A΂Η邱Ƃł܂BGWjÁA璁oƁA͂肳邱ƁAĂ̂悤ȔZp҂͎ɂ‚ČP󂯂Ă܂B͋ZpIȔfAʏ̓rWlX̖𗝉邱Ƃł邽߁AȒPɉ邱Ƃł܂B + +΂΋Zp҈ȊO̐ĺAȂ̋ZpIfƊO҂̌𑊏悳邱ƂɂĂȂAǂS̓Iȉ􂪑݂ƂɁAD瓦₷ĐƂƂ]ȒPɂ\[VĂ邱Ƃ܂B͌lIɂ͋ɒ[ȃvO~ODłBȂȂA̔ɑΏ邩łBςfACfAɌѕt邱ƂŁARXgƗv̍ŗǂ̑gݍ킹łACfAȒPɌ‚邱Ƃł܂B + +Next [Advanced skills](../../3-Advanced) diff --git a/jp/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/jp/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..310d709 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,15 @@ +# How to Stay Motivated +[//]: # (Version:1.0.0) +vO}[AALvȁA܂͋C̗lH쐬Ƃ~ɂčӗ~Ă邱Ƃ́Af炵AׂłB̗v]́AvO}[ɂƂĂjo[TłȂAvO}[ԂŔɋʂĂ邽߁Ã̖o[Ƃ͕Ă܂B + +ɂ͎pIdvȌʂ܂BvO}[AȂALvȁA܂͋Ĉ̗łȂƂ悤߂ꂽꍇAނ͒ႢmC‚ł傤BXAȁAދȂ̂č邽߂ɂ̂܂BAǂ̂ƂAy݂͉Ђ̂߂ɍł҂ł傤B + +炩ɁAɂ͂‚̓@ÂZpgݍ܂ꂽƊEŜ܂BłvO~OL͎̎̂ƂłF + +- dɍœKȌgpĂB +- VZpAAZpKp@T܂B +- ꂼ̃vWFNgŁẤAwсA悤ɂĂB + +ŌɁA”\ł΁A̎d̉eAlIɓ@t̂Ƃđ肵܂BƂ΁AoOCƂACoO̐JEg邱Ƃ́Aꂪ܂݂邩ȂƂ͖֌WłẢЉ”\Ȍ菬ȕ@łqlɒ񋟂܂BAꂼ̃oOKȌڋqɌѕt邱Ƃ́ǍlIȓ@łB + +Next [How to be Widely Trusted](02-How-to-be-Widely-Trusted.md) diff --git a/jp/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md b/jp/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md new file mode 100644 index 0000000..4420a02 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -0,0 +1,7 @@ +# How to be Widely Trusted +[//]: # (Version:1.0.0) +ȂM邽߂ɂ́AMł̂łȂ΂Ȃ܂B ȂKv܂B NȂɂ‚ĒmĂȂ΁AȂɂ͐M͓܂B Ȃ̃`[Cĝ悤ȁAȂɋ߂lƁA͖ł͂܂B Ȃ́AȂ̕`[O̐lɕqŗLvł邱ƂɂĐMm܂B XAN̐Mp𗐗pAsȉb߂邱Ƃ܂B Ă͂܂BDӂ𐋍s邽߂ɂȂȂ΂ȂȂƂĂB + +ȂȂƂmĂӂȂłB `[[gł͂Ȃlɂ́Au̓̏ォEɕȂvƁu߂邱ƂłȂvƂ̖mȋʂȂ΂ȂȂ܂B + +Next [How to Tradeoff Time vs. Space](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/jp/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md b/jp/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md new file mode 100644 index 0000000..d9e4f4a --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -0,0 +1,15 @@ +# How to Tradeoff Time vs. Space +[//]: # (Version:1.0.0) +Ȃ͑wɍsȂĂǂvO}[ɂȂ邱Ƃł܂A{IȌvZG_mȂĂADꂽԃvO}[ɂȂ邱Ƃ͂ł܂BȂ 'big O'\L@mKv͂܂񂪁A͌lIɂ́A '莞'A 'n log n' 'n squared'̈Ⴂ𗝉łȂ΂ȂȂƎv܂B̒mȂĂAԂƋԂƂ̃g[hIt̎dm邱Ƃł邩܂񂪁As݂̏ꍇAƂ̃R~jP[V̂߂̊młՂ͂܂B + +ASY̐݌v܂͗ɂẮAsɗv鎞Ԃ͓͂̃TCY̊֐ł邱Ƃ܂Bꂪ^łƂAASY̍ň/\z/ŗǃP[X̎sԂ́ATCY̑ΐi$ n $jɔႷ 'n log n'ƌƂł܂B\L@є@́Af[^\ɂĐ߂ԂɂKp邱ƂłB + +ɂƂāAvZ̕G̗_͔Awقǐ[Aď͉ɍŝłI + +ԁivZbT[ETCNjƃXy[Xi[j݂͂Ƀg[hItł܂BGWjAO͑ËłA͗ǂłBǨnIł͂܂BAʓIɂ́AfR[hKvƂɌvZԂ]ɂāA茵ɃGR[h邱ƂŃXy[Xߖł܂BLbV̈ѐێȂ΂ȂȂ߁ALbV邱ƂŎԂߖ񂷂邱Ƃł܂B‚܂Ã[JRs[i[邽߂̃Xy[X₷Ƃł܂Bf[^\ł葽̏ێ邱ƂɂāAԂߖ񂷂邱Ƃł܂B͒ʏA킸ȃXy[XKvƂ܂񂪁AASYGɂȂ”\܂B + +/Ԃ̃g[hItP邱Ƃ́A΂Έ܂͑Iɕς邱ƂłBAɎgޑOɁAȂPĂ̂A{ɍłPKvȂ̂Ȃ̂Agɐq˂ĂBASYōƂ̂͊yłAł͂Ȃ̂P邱ƂŖڗႢ͂ȂAeXg̕S邱Ƃ͂܂B + +̃Rs[^̃́AvZbTԂƂ͈قȂAǂɏՓ˂܂ŎgpĂȂ߁AɌ܂Bs͉œIłB풓Ȃ΂ȂȂ̃vOւ̉eA蓖Ă⊄蓖Ă鎞ԂȂǁAgp邽߂̉BꂽRXg܂BXs[hグ邽߂ɃXy[X菜OɁATdɌĂB + +Next [How to Stress Test](04-How-to-Stress-Test.md) diff --git a/jp/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md b/jp/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md new file mode 100644 index 0000000..561314a --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -0,0 +1,17 @@ +# How to Stress Test +[//]: # (Version:1.0.0) +XgXeXg͊yłBŏ́AXgXeXg̖ړÍAVXẻׂœ삷邩ǂ𒲂ׂ邱ƂłBۂɂ́AVXẻׂœ삷͈̂ʓIłAׂ\ɏdꍇ͉炩̕@œ삵܂B͂*܂*{LO* [1] ɓĂĂ܂B‚̗O邩܂񂪁AقƂǏɁuǁv܂BXgXeXg̖ړÍAǂǂɂ邩cAǂɉ@𗝉邱ƂłB + +XgXeXǧv́A҂邱Ƃ𐳊mɖmɂ̂ɖ𗧂‚Ƃ̂ŁAvWFNg̑ɊJKv܂B Weby[WvߎSȎŝ2błH 500l̓[U[\łH͂AˑĂ܂AvɓVXe݌vƂ͓mKv܂BXgXeXǵAp\ɔł悤ɃfKv܂B 500l̕sŗ\s\ȐlԂVXegēɊȒPɃV~[g邱Ƃ͎ۂɂ͉”\ł͂܂񂪁AȂƂ500̃V~[V쐬A炪s”\̂镔fO悤Ƃ܂B + +XgXeXgł́AyׂŎnAǂɓ܂ŁA͑x̓TCYȂǂ̐@ɉăVXe[h܂BAvZbTAI / OAlbg[Nш敝A܂̓f[^̋́AǂȂ̃j[Y𖞂ɂ͋߂ꍇ́A{glbNƂȂ郊\[Xiʏ͎xzIȂ́jcĂBɁAǂ𓮂@‚܂BEH[𓮂A‚܂VXełő啉ׂ𑝂₷Ƃ́ǍׂyVXẽptH[}XቺAۂɊQ”\܂BʏAׂyꍇ̃ptH[}X́Aׂdꍇ̃ptH[}XdvłB + +Ȃ͂̐_If\z邽߂ɁA‚̈قȂ鎟ŽȂ΂ȂȂ܂BP̋Zpŏ\ł͂ȂBƂ΁AMOł́AVXe2‚̃CxgԂ̃EH[NbNԂ悭m邱Ƃ܂ATdɍ\zȂAgpf[^\TCỶŽ͂܂BlɁAŐṼVXeł́ÃRs[^Ƒ̃\tgEFAVXe͂Ô\܂BɁAǂɓƂi‚܂A͂̑傫ɉăptH[}X񒼐IłjȂ̃\tgEFAVXe̓{glbNɂȂ”\܂BQĂ邷ׂẴ}ṼvZbTׂ𑪒肷邾łĂÃVXẻŽ͔ɖ𗧂܂B + +ǂǂɂ邩m邱Ƃ́Aǂ𓮂łȂA\”\񋟂ărWlXIɊǗł悤ɂ邽߂ɂsŒłB + +--- + +[1] "to hit" + +Next [How to Balance Brevity and Abstraction](05-How-to-Balance-Brevity-and-Abstraction.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md b/jp/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md new file mode 100644 index 0000000..f0a6bd6 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -0,0 +1,9 @@ +# How to Balance Brevity and Abstraction +[//]: # (Version:1.0.0) +ۉ̓vO~OɂƂďdvłBȂ͂ǂ̂悤ɒۓIłKv邩TdɑIKv܂BvO}[̔Mӂ́A΂Ζ{ɗLpȂ̂ۓx߂܂B‚̒́AۂɃR[h܂܂ȂNX쐬AۓIȂ̂񋟂ȊO͉ȂNX쐬ꍇłB̖͂͗ł܂AR[h̊Ȍ̉l͒ۉ̉lɑ΂đ肳Ȃ΂Ȃ܂B܁AMIȗz`҂ԈႢƂƂ܂BvWFNg̊Jnɂ́AۓIɎv鑽̃NX`A”\̂邷ׂĂ̎ԂƐ܂BvWFNgisAJ荞ނɂ‚āAR[ĥGɂȂ܂B֐{̂́AKvȏɒȂ܂B̃NX́A̕SłAvbV[ł͖܂Bۉɔ₳ꂽGlM[AZȒPɕۂ‚߂ɔ₳ꂽȂAŏIIȌʂ͂ǂ̂ɂȂ܂B͓@IvO~O*̈`ԂłB́A[Paul Grahamɂ[ 'Succinctness is Power'ihttp://www.paulgraham.com/power.htmlj̋L߂܂B + +*B*IuWFNgwvO~O*Ȃǂ֗̕ȃeNjbNɊ֘AhO}܂B̋ZṕA1‚̃R[h𒊏ۓIȂ̂ɂAω\B͌lIɂ́A̓@IȃR[h𐶐ׂł͂ȂƎv܂BƂ΁Aϐ̂GNX|[YȂ悤ɁA~[^ƃANZT̔wɂIuWFNg̐ϐ\ɂāAɑ΂鏬ȃC^[tF[X󂯓X^C͗eFĂ܂BɂAĂяoR[hɉe^ɂ̕ϐ̎ύX邱ƂłAɈ肵APIJȂ΂ȂȂCuC^[ɂƂĂ͂炭K؂łB́Ã`[R[OR[hLĂ̂ŁAĂяoȒPɃR[[Ɠ悤ɍăR[fBO邱Ƃł̂ŁA̗_̌̃RXgƂ͎vȂB 4‚܂5‚̗]ȃR[hśA̓@Iȗv̂߂Ɏx߂̏d㏞łB + +ڐAɂl̖肪܂BR[hʂ̃Rs[^ARpCA\tgEFAVXeA܂̓vbgtH[ɈڐA邩AȒPɈڐAKv܂H|[^uł͂ȂAZĊȒPɈڐAłR[h́AڐA”\ȃR[hDĂƎv܂BDBMSɌŗL̃f[^x[XNG쐬NXȂǁA|[^ułȂR[hw肳ꂽ̈Ɍ肷邱Ƃ͔rIȒPłAmɗǂlłB + +Next [How to Learn New Skills](06-How-to-Learn-New-Skills.md) diff --git a/jp/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md b/jp/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md new file mode 100644 index 0000000..4f75713 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -0,0 +1,13 @@ +# How to Learn New Skills +[//]: # (Version:1.0.0) +VXLAɔZpXLwԂƂ́AׂĂ̐l̍ő̊y݂łBقƂǂ̊Ƃ́AꂪvO}[̃`x[Vǂ̂炢邩ɂāAǂmC𓾂邱Ƃł܂B + +lԂ͂ĊwԁBubN[fBOƃNXƂ͕֗łBAȂ̓vOƂ̂ȂvO}[𑸌h邱Ƃł܂HXLwԂ߂ɂ́ÃXL𔭊ł銰eȈʒuɎguȂ΂Ȃ܂BVvO~OwԂƂ́A傫ȃvWFNgsOɏȃvWFNgsĂ݂ĂB\tgEFAvWFNgǗ@wԂƂ́A܂Ȃ̂ǗĂB + +ǂw҂́Ał邱Ƃɑ̂ł͂܂񂪁A{͂邩ɗDĂ܂Bނ̒mƈɁAݓIȃ^[Ȃɒ񋟂邱Ƃ͂ł܂HŒłA׋ĎԂ𖳑ʂɂȂ悤ɏシׂłB + +Ȃ̏iɐȌPĂ炤悤ɂĂBAȂwтVXLŗVł̂Ɠ炢̎Ԃ͂قǗǂȂƗĂ܂BAsSȐEł́Ag[jO߂̂ȒPłBȃg[jȎ́A[H҂Ău`ʂĐQĂ邾łB + +Ȃl𓱂ꍇAނ炪ĂK؂ȋK͂̃vWFNg蓖Ă邱ƂɂāAނ炪ǂ̂悤ɊwсA邩𗝉BvO}[ɂƂčłdvȃXL͋ZpIȂ̂ł͂ȂƂYȂłBȂ̐lXɁAECAAR~jP[VėK@^܂傤B + +Next [Learn to Type](07-Learn-to-Type.md) diff --git a/jp/2-Intermediate/Personal-Skills/07-Learn-to-Type.md b/jp/2-Intermediate/Personal-Skills/07-Learn-to-Type.md new file mode 100644 index 0000000..55aa408 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -0,0 +1,5 @@ +# Learn to Type +[//]: # (Version:1.0.0) +^b`^CvwԁB ͒̃XLłBR[hƂ͔ɓA͂鑬x֌WŁAR[h̏ɎԂȂ悤ɂ邱Ƃł܂B AԃvO}[ł΁A炭Ȃ̓⑼lɎR̂ɑ̎Ԃ₷ł傤B ͂Ȃ̃R~bgg̊yeXgłB ̂悤ȂƂwԂ̂͂܂ʔȂp̎Ԃ܂B `ɂ΁AMichael TiemannMCCɂƂAĺAނ̃L[Xg[NɂĐꂽn𕷂߂ɃhÅOɗ‚ƂɂȂ܂B + +Next [How to Do Integration Testing](08-How-to-Do-Integration-Testing.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md b/jp/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md new file mode 100644 index 0000000..cbaa77a --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -0,0 +1,7 @@ +# How to Do Integration Testing +[//]: # (Version:1.0.0) +eXǵAP̃eXgꂽ܂܂ȃR|[lg̓eXgłB ͍łAeXgŏoĂB Ȃ̌ςƂȂ̃XPW[ɂ̎Ԃ܂߂Kv܂B + +zIɂ́A𖾎IɍsKvtF[YŏIiKɂȂ悤ɃvWFNgҐ̂zIłB vWFNg̉ߒŊ̂iKIɓ͂邩ɗDĂ܂B ނ𓾂Ȃꍇ͒Ӑ[ςĂB + +Next [Communication Languages](09-Communication-Languages.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Personal-Skills/09-Communication-Languages.md b/jp/2-Intermediate/Personal-Skills/09-Communication-Languages.md new file mode 100644 index 0000000..85557fa --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -0,0 +1,11 @@ +# Communication Languages +[//]: # (Version:1.0.0) +vO~Oł͂ȂAʐM*ł`Iɒ`ꂽ\VXê‚̌ꂪ܂B́AWʂR~jP[VeՂɂ悤ɓʂɐ݌vĂ܂B 2003Nɂ́A̒ōłdvȂ̂UMLAXMLASQLłBȂ͂悭R~jP[VAŽgׂ߂邽߂ɁA炷ׂĂɐʂĂKv܂B + +UMĹA݌vLq}ʂ쐬邽߂̖LȐȃVXełB̔́AꂪrWAłtH[}łA҂Ɠǎ҂̗UMLmĂ΁Aʂ̏`邱Ƃł܂BȂ͂ɂ‚ĒmKv܂BȂȂA̒ŃfUC`邱Ƃ邩łBɐIɌUML}ʂ쐬邽߂̔ɗLpȃc[܂B̏ꍇAUML͐Ȃ̂łA݌v}ʂɂ͂P*{bNXƖ*X^CgpĂ܂BÁAUMLȂƂe׋̂ɂ҂łƊmMĂ܂B + +XML͐VW`邽߂̕WłBf[^̖̉ł͂܂񂪁A܂łꂪ݂邩̂悤ɕ\邱Ƃ܂BނAf[^̍łދȕ̎AȂ킿\`V[PXɍ\A\ɍ\͂邱Ƃ}鎩łBۂɕKvƎv̂̂ق̈ꕔłɂ炸A‚̃^Cv`FbNƐ`FbN܂B + +SQĹAvO~Oł͂Ȃɋ͂ŖLxȃf[^NGё쌾łBWꂽRAdvł͂ȂÃoG[Viʏ͐iˑj܂B SQĹA[Vif[^x[X* lingua franca *łB[ViEf[^x[X̗̉b󂯂”\̂镪ōƂꍇ΁AƂȂꍇ܂ASQL̍\ƈӖɂ‚Ă͊{IɗĂKv܂B + +Next [Heavy Tools](10-Heavy-Tools.md) diff --git a/jp/2-Intermediate/Personal-Skills/10-Heavy-Tools.md b/jp/2-Intermediate/Personal-Skills/10-Heavy-Tools.md new file mode 100644 index 0000000..0466cf2 --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -0,0 +1,14 @@ +# Heavy Tools + [//]: # (Version:1.0.0) +̋Zpiނɂ‚āA\tgEFAZṕAzłȂ̂AAViAWꂽiALyȐiɈڍsĂ܂B ̏dH͑傫ȕׂ邱Ƃ܂AЈ邱ƂAɑ傫ȓKvƂ܂B ԃvO}[́AǗ@ƁAŽgpׂA܂͍lׂmKv܂B + +̐Sɂ́Ałdc[̂‚܂F + +- [Vif[^x[XA +- SGWA +- wCu[A +- OpenGLA +- XMLp[T[A +- XvbhV[gB + +Next [How to analyze data](11-How-to-analyze-data.md) diff --git a/jp/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md b/jp/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md new file mode 100644 index 0000000..f6f4b2f --- /dev/null +++ b/jp/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -0,0 +1,11 @@ +# How to analyze data +[//]: # (Version:1.0.0) +f[^͂́A\tgEFAJ̏iK̃vZXŁArWlXANeBreB𒲂ׁA\tgEFAAvP[Vɕϊ邽߂̗v‚ovZXłB͐Ȓ`łAf[^͂̓VXeAiXgɔCĂׂsłƐM邩܂񂪁AvO}[͒N݌v̂R[fBO邱Ƃɏœ_𓖂ĂׂłBɃ\tgEFAGWjAÕp_Cɏ]΁A܂BoLxȃvO}[fUCi[ɂȂAsfUCi[rWlXAiXgɂȂAׂẴf[^vɂ‚čl邱ƂłAmȃ^XNs邱Ƃł܂B́Af[^ׂẴvO~O̒jƂȂ邽߁ASɂ͐mł͂܂BȂ̃vOʼnĂAȂ͈ړĂ邩Af[^ύXĂ܂BrWlXAiXg̓j[YK͂ɕ͂Ă܂B\tgEFAfUCi[́Â悤ȋK͂ɍi荞ŁA肪Ȃ̊̏ɒƁAIȃASYKpĊ̃f[^ړ邾łB + +ł͂܂B + +ǂ̒iKŌĂAf[^͂܂݌vꂽAvP[V̎Ȋ֐SłBrWlXAiXgڋq̗vǂ̂悤ɗv擾Ă邩ڂ΁Af[^{IȖʂƂ킩܂BAiXg͂f[^t[_CAO쐬AׂẴf[^\[XʂAt[`܂Bǂ̃f[^VXëꕔɂ邩𖾊mɂŁAf[^x[X֌WAf[^vgRAуt@C`̊ϓ_A݌v҂̓f[^\[X𐮌`ăvO}ɓn܂BAvZX͂܂IĂ܂B̓Oꂵf[^vZX̌łĂivO}jA”\Ȍŗǂ̕@Ńf[^𕪐͂Kv邩łBȂ̎d̍ŏIśA‚̌̕łNiklaus Wirth̒jbZ[WłB "ASY+f[^\=vO"PƂŃASY𗧂Ă邱Ƃ͌Ă܂BׂẴASÝAȂƂ1‚̃f[^ɑ΂ĉsƂɂȂĂ܂B + +āAASY͐^Ŏԗւ]Ȃ̂ŁAlȂ̂߂ɓ肵f[^ƃR[h߂̂ɕKvȃf[^̗𕪐͂Kv܂BȒPȗł́A肪薾mɂȂ܂BCǔ[`Ă܂BȂ̎dlɂƁA[U[̓WAҁA^CgAoŎЁANAy[W̑gݍ킹ŏЂIł܂B[`̍ŏIIȖڕẂAobNGhEf[^x[X邽߂̐SQL𐶐邱ƂłB̗vɊÂāA‚̑I܂BuswitchvXe[ggA܂͕́uifvXe[gggpāAeRg[ԂɃ`FbN܂Bf[^Rg[̔z쐬Aevfݒ肳Ă邩ǂ`FbN܂BׂĂ̓̃Rg[p钊ۃRg[IuWFNg쐬i܂͎gpjACxghuGWɐڑ܂Bvɓ̏ōڂ`FbNĂ邱ƂmFāANG̃ptH[}X`[jO邱ƂKvȏꍇ́AR|[lg̃c[gpSQL쐬邱Ƃ邱Ƃł܂B̂ƂAASY̑ÍAgpA܂͍쐬f[^ɂĈقȂ܂B̂悤Ȍ́AIȃASYƔߎSȃASYƂ̊Ԃׂ̂Ă̈Ⴂ𐶂”\BAOł͂܂BȂ́AȂ̃R[hɖOt̕ϐ12ŽgpA܂łǂIɂ邱Ƃł܂BÂ悤ȃR[h͊ȒPɕێłȂ܂B炭Aϐ̓K؂ȃReiI邱ƂœXs[hۂ‚ƂłAɁANɂ́AR[h悭ł悤ɂȂ܂BɁAmɒ`ꂽf[^\I邱ƂŁAR[h̏s킸ɃR[h̋@\g邱Ƃł܂BIɂ́Af[^̑IɂāAR[h̏IɃR[hԂ܂܂B‚̗Ă݂܂傤Bvl̂߂̐Hו͂܂BAiO̕ʂ̒PłȂ΂ȂȂA3ˆȏ̃AiOŽׂ̂Ă̒P‚邱ƂȂ̎dłƂ܂傤BvZ̎dƍlȂ΁AȂ͖̓w͂ɏIAePׂ̂Ă̑gݍ킹āAXg̑̒PƔr悤Ƃ܂BA茳̃f[^𕪐͂ƁAPꂻ̂̂Ƃ̃̕\[gꂽzIDƂĊ܂ރR[hŊeP\Ƃł܂B̂悤Ȓmgɂ‚āAAiO‚邱Ƃ́Alj̃tB[hŃXg\[gAIDL̂IԂƂӖ܂Bu[gtH[XASÝAsɐ邱Ƃ܂AX}[gȃASY͂ق̐błBɒʂĂ邱̗oĂĂB + +Next [Team Skills - How to Manage Development Time](../Team-Skills/01-How-to-Manage-Development-Time.md) diff --git a/jp/2-Intermediate/README.md b/jp/2-Intermediate/README.md new file mode 100644 index 0000000..75294f7 --- /dev/null +++ b/jp/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. Intermediate +[//]: # (Version:1.0.0) +- Personal Skills + - [How to Stay Motivated](Personal-Skills/01-How-to-Stay-Motivated.md) + - [How to be Widely Trusted](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [How to Tradeoff Time vs. Space](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [How to Stress Test](Personal-Skills/04-How-to-Stress-Test.md) + - [How to Balance Brevity and Abstraction](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [How to Learn New Skills](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Learn to Type](Personal-Skills/07-Learn-to-Type.md) + - [How to Do Integration Testing](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Communication Languages](Personal-Skills/09-Communication-Languages.md) + - [Heavy Tools](Personal-Skills/10-Heavy-Tools.md) + - [How to analyze data](Personal-Skills/11-How-to-analyze-data.md) +- Team Skills + - [How to Manage Development Time](Team-Skills/01-How-to-Manage-Development-Time.md) + - [How to Manage Third-Party Software Risks](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [How to Manage Consultants](Team-Skills/03-How-to-Manage-Consultants.md) + - [How to Communicate the Right Amount](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [How to Disagree Honestly and Get Away with It](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- Judgment + - [How to Tradeoff Quality Against Development Time](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [How to Manage Software System Dependence](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [How to Decide if Software is Too Immature](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [How to Make a Buy vs. Build Decision](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [How to Grow Professionally](Judgment/05-How-to-Grow-zProfessionally.md) + - [How to Evaluate Interviewees](Judgment/06-How-to-Evaluate-Interviewees.md) + - [How to Know When to Apply Fancy Computer Science](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [How to Talk to Non-Engineers](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/jp/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md b/jp/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md new file mode 100644 index 0000000..44ae1d7 --- /dev/null +++ b/jp/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -0,0 +1,11 @@ +# How to Manage Development Time +[//]: # (Version:1.0.0) +JԂǗ邽߂ɁAȌōŐṼvWFNgvێBvWFNgvƂ́AςAXPW[Ais󋵂}CXg[Aς̊e^XNւ̎̃`[܂͎̎Ԃ̊蓖ĂłBiۏؒS҂Ƃ̖ʒkAhLe[V̏A@̒ȂǁAYĂ͂ȂȂƂ܂B`[ɎQĂꍇAvWFNǧv́AJnƏI̗ōӂӂłȂ΂Ȃ܂B + +vWFNgv́AȂǂ̂悤ɑgDĂ邩̂ł͂ȂAӎvx邽߂ɑ݂܂BvWFNgv悪邩ŐVłȂꍇAӎvɂ͖ɗȂł傤Bۂɂ́Ǎ͌lɊւ̂łBvƂȂ̔f́Adlʂ̐lɈڂׂǂ肳܂B}CXg[͂Ȃ̐i܂Bt@V[ȃvWFNgvc[gpĂꍇ́AvWFNgBig Design Up FrontiBDUFj쐬̂ɘf킳̂ł͂ȂAgpĊȌōŐV̏Ԃێ܂B + +}CXg[Ăꍇ́Aiɂ̃vWFNg̗\芮̋zƂm点ȂǁAɍsKv܂BςƃXPW[́AĊȂ̂ł͂Ȃ܂B́AȂvWFNǧ㔼ŌȂ₤ƂłƂoo܂BȂBAȂߑ]ĂƂƂȂߏ]Ô\܂BāAȂDۂɂ炸Av悳ꂽvWFNg̊͂łɃXbvĂ܂B + +`[~[eBOAfAA\肳ꂽIȊAeXgAO҂Ƃ̑ΏAaCAxɁAĩeiXAJ‹̃eiXȂǁAvɎԂ܂܂Ă邱ƂmFĂBvWFNgv́AȂ₠Ȃ̃`[Ă邱ƂO҂iɌ@ƂĖ𗧂܂B̂߁AZԂōŐV̂̂ɂKv܂B + +Next [How to Manage Third-Party Software Risks](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/jp/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md b/jp/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md new file mode 100644 index 0000000..470d295 --- /dev/null +++ b/jp/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -0,0 +1,11 @@ +# How to Manage Third-Party Software Risks +[//]: # (Version:1.0.0) +vWFNg͂΂΁AǗĂȂgDɂč쐬ꂽ\tgEFAɈˑ܂B֌W邷ׂĂ̐lFȂ΂ȂȂO҂̃\tgEFAɂ͑傫ȃXN܂B + +āACɂǂȊ]Ă͂܂B VapoŕA񑩂Ă邪܂p”\ł͂ȂƎ咣Ă\tgEFÂƂłB͍ň̕@łB̋@\̐i̓tɃ[XƂ\tgEFAƂ̖񑩂Pɉ^Iɂ̂͌ł͂ȂBSɖAȂ𕷂ƂY邱Ƃ͂ƌłBȂ̉ЂgpĂ鏑ނɏ߂Ă͂܂B + +T[hp[eB̃\tgEFA͊ĂȂꍇłA͂܂댯łAȂƂ͎gނƂł郊XNłBT[hp[eB̃\tgEFAgp邱ƂĂꍇ́Aɕ]ĕ]Kv܂BlX́A3‚̐îꂼɂ‚ēKؐ]̂2TԂ2ƕĂȂ܂񂪁A”\Ȍ葁sKv܂BK؂ȕ]ȂɁÃRXg𐳊mɐ肷邱Ƃ͂ł܂B + +̖ړÎ߂̊̃T[hp[eB\tgEFA̓K𗝉邱Ƃ́AɕIȒmłB͔ɎϓIŁAʂɐƂɋZĂ܂B̐Ƃ‚邱Ƃł΁A̎Ԃߖł܂B̏ꍇAvWFNg̓T[hp[eB̃\tgEFAVXeɈˑ邽߁AsƃvWFNg͎s܂B̂悤ȃXNXPW[ŏʂŖmɕ\ĂBXN𑁊ɏłȂꍇ́Agp”\ȕʂ̃VXe@\ō쐬ȂǁAً}Ήv𗧂ĂĂBXPW[͏CɈˑȂ悤ɂĂB + +Next [How to Manage Consultants](03-How-to-Manage-Consultants.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/jp/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..b0cbb82 --- /dev/null +++ b/jp/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,9 @@ +# How to Manage Consultants +[//]: # (Version:1.0.0) +RT^ggp܂AɗȂłBނ͂΂炵lXłA傢ɑhׂłBނ͑̈قȂvWFNgĂ̂ŁÃeNmWvO~OeNjbNɂ‚Ă̒mAȂ̂̂΂Ε܂BgpőP̕@́AtГŋ邱Ƃł悤ɂ邱ƂłB + +Aʏ݂̋Ǝ݂wԂ̂ɏ\ȎԂȂ߁Aʏ̏]ƈƓoŃ`[ɎQ邱Ƃ͂ł܂Bނ̍IR~bgg͂͂邩ɒႢłBނ͂ȒPɓƂł܂BЂ܂ȂAނ̗v͂܂蓾Ȃ܂B‚͗ǂA‚͕ςŁA‚͈łAȂ̃RT^g̑I͂Ȃ̏]ƈ̑IقǐTdł͂Ȃł傤AȂ͈̂𓾂ł傤B + +RT^gR[h‚ȂATdɌȂ΂Ȃ܂Br[ĂȂ傫ȃR[hubÑXN𔺂vWFNg̍Ōɂ͓Bł܂B͎ۂɂׂ͂Ẵ`[o[ɓĂ͂܂܂Aʏ͂Ȃɋ߂`[o[̒m܂B + +Next [How to Communicate the Right Amount](04-How-to-Communicate-the-Right-Amount.md) \ No newline at end of file diff --git a/jp/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md b/jp/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md new file mode 100644 index 0000000..b0daa68 --- /dev/null +++ b/jp/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -0,0 +1,7 @@ +# How to Communicate the Right Amount +[//]: # (Version:1.0.0) +TdɉclĂB ̊ԂɎQ҂̐|*p܂B cKvȏꍇ܂Aʏ͏K͂łB K͂ȉcł̃R~jP[V̎͌サAS̓IɖʂɂȂ鎞Ԃ͏ȂȂ܂B cɒNދĂꍇ́AcׂłƂƂĂB + +̃R~jP[V𑣐i邽߂ɂ́A”\Ȍ̂ƂsȂ΂ȂȂB ֗ȍƂ́A̎ԂƂ̃`ɍs܂B ̊Ƃ̎FT|[gĂȂƂ͎cOłB + +Next [How to Disagree Honestly and Get Away with It](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/jp/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md b/jp/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md new file mode 100644 index 0000000..7d35e8b --- /dev/null +++ b/jp/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -0,0 +1,11 @@ +# How to Disagree Honestly and Get Away with It +[//]: # (Version:1.0.0) +ӌ̕sv͗ǂfD̋@łAɏKv܂BȂvlK؂ɕ\A肪OɕƎvƂĂ܂B̏ꍇ͉Ƃ͂܂BȂɓӂȂĂAȂ̔wɗ‚ǂ߂ׂłBȂӂȂɂ炸̌x邱Ƃł΁AȂB́AȂƗĂACGXE}ł͂ȂAƃ`[Ev[[𑸏dĂ邽߁AȂǂقNjMdȂ̂Ă܂B + +ӎv҂Ȃ̈ӌ\ɐȂƂɁAȂ΂錈Ƃ܂B̌AЂ╔̗vɊÂĖN邩ǂ]Kv܂BꂪȂ̈ӌ̏ȊԈႢłȂA͍čl鉿lȂ܂BȂ̈ӌɑ傫ȊԈႢꍇ́Ac_񎦂Kv܂B + +ʏA͖ł͂܂BXgX̑󋵂ł́A‚̃p[\ieB^Cvł́A͌lIȂ̂ɂ‚Ȃ”\܂BƂ΁AɗDꂽvO}[̂Ȃɂ́AꂪԈĂƐM鐳ȗRꍇłAӎvɒ킷邽߂ɕKvȎMȂ̂܂Bň̏󋵂ł́Aӎv҂͕słǍɑ΂lIȒƌȂB̂悤ȏ󋵂ł́AlX͔]঒ނ̕ɔ邱ƂoĂƂőPłBȂ͋c_JŒ񎦂AVmǂ̂悤Ɍ肪ꂽĂׂ݂łB + +ӎv肪t]Ă邩ǂɂ炸A֌肪Sɒꂽ̂ŁAȂ́uȂɂvƌƂ͌ĂłȂƂYȂłB + +Next [Judgment - How to Tradeoff Quality Against Development Time](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/jp/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md b/jp/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md new file mode 100644 index 0000000..8fbf4ae --- /dev/null +++ b/jp/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -0,0 +1,11 @@ +# How to Fight Schedule Pressure +[//]: # (Version:1.0.0) +i܂ł̎Ԃ̒ZḱAꂽivɒ񋟂ƂvbV[łB͍I𔽉fĂA鎞_܂ŌSȂ̂ŗǂłBXPW[͂́AB”\ȑxB鈳͂łAʂłAsSłA܂ɂʓIłB + +XPW[͂͂‚̗Rő݂܂BvO}[𖱂߂ĺAĂ鋭dϗƃvO}[ɂȂ邱ƂǂقNJy\ɗĂ܂B炭Aނ͎̍sɓêŁA߂邱Ƃ́A葁ɓB悤ɂƓ悤ɂȂƐMĂ܂B͂炭ۂɂ͓Ă͂܂܂Aʂ͔ɏA͔ɑ傫łBɁAނ͎ۂɃ\tgEFA邽߂ɕKvȂ̂ɂ‚Ă͌܂B邱ƂłAꎩ̂쐬邱ƂłȂƂƂ́Aނ炪łB̂Ƃ́As꓊܂ł̎Ԃ̈ƂɊւvO}[̑łB + +XPW[̈͂Ɛ키߂̌́A^CEgDE}[Pbg̈͂ɕς邱ƂłBp”\ȘJƐiƂ̊֌WŽ邽߂̕@BŁAڍׂȁAčłdvȂ̂oƂ́As߂̍őP̕@łBɂ́A”\̂@\̃g[hItɂ‚Ă̓K؂ȊǗ̌”\ɂƂlj̗_܂B + +ς肪ɂȂ΂ȂȂdvȓ@́AJ͂قڔ񈳏k̉t̂łƂƂłBRei̗eψȏ̃ReiɂƑ̐邱Ƃł܂BӖł́AvO}[́u΁vƌĂ͂܂񂪁AuXq͂Ȃ]ނƂ߂ł傤HvƂmȌςốAvO}[ɂƂĂ̌hӂ߂邱ƂɂȂ܂B͑̐Ƃ̍słBvO}[̘J͂ł傤B񌻎IȃXPW[ݒ肷邱Ƃ́ANɂƂĂɊ邱ƂłBvO}͂񂴂肷邱Ƃ͂ł܂Bނɔ񌻎IȂƂ͖̂ȂƂłB Extreme Programming͂𑝕A̎ɃvZX\z܂B́AׂĂ̓ǎ҂gp̂ɏ\ȂقǍK^ɂȂ邱ƂĂ܂B + +Next [How to Understand the User](02-How-to-Understand-the-User.md) \ No newline at end of file diff --git a/jp/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md b/jp/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md new file mode 100644 index 0000000..de74aaf --- /dev/null +++ b/jp/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -0,0 +1,17 @@ +# How to Understand the User +[//]: # (Version:1.0.0) +[U[𗝉AiɃ[U[𗝉̂͂Ȃ̋`łB[U[͎̐i̍쐬ɖڂɊւĂȂ߁A܂B + +- [U[́AʓIɒZ܂B +- [U[͎̎dĂ܂Bނ͎ɁA傫ȉPł͂ȂAȂ̐ȉȉPlł傤B +- [U[́Ai[U[̑Sg\rW‚Ƃ͂ł܂B + +ނ炪{ɗ~̂^̂͂Ȃ̋`łAނ炪]ނƌĂ̂ł͂܂BAނɒĂAȂ̒ĂȂn߂Oɖ{ɖ]ނ̂ł邱Ƃɓӂ̂ǂłArW͂Ȃ܂BɊւ邠Ȃg̃ACfAɑ΂邠Ȃ̐M͕ς͂łBڋq{ɖ]ł邱ƂmƂϓ_́Aƌ̗Kv܂BvO}[͐݌vƍ쐬PĂ܂Bš҂́AlX]ނ̂𗝉悤ɌPĂ܂B2‚̎ނ̐lA܂͓l2‚̍laĈꏏɓāArW肷ŗǂ̋@^܂B + +[U[ƈꏏɉ߂ԂȂ΂ȂقǁAۂɉ邩𗝉ł悤ɂȂ܂Bł邾ɑ΂ĂȂ̃ACfAƂׂłBȂłȂHׂĈނׂłB + +Guy Kawasaki [Rules]́A[U[ƂɉāA[U[̍sĎ邱Ƃ̏dvĂ܂B + +͐Ǝ҂RT^gA΂Δނ炪{ɖ]ނ̂̐S̒Ŗmɂ悤Ɍڋqɑi傫ȖĂƐMĂ܂BȂRT^gɂȂ낤ƎvĂȂA͂Ȃ̃NCAgAނ̖mȓ̒łȂAނ̎蒠ɊÂđIԂƂ߂܂B + +Next [How to Get a Promotion](03-How-to-Get-a-Promotion.md) \ No newline at end of file diff --git a/jp/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md b/jp/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md new file mode 100644 index 0000000..0765719 --- /dev/null +++ b/jp/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -0,0 +1,13 @@ +# How to Get a Promotion +[//]: # (Version:1.0.0) +ɏiɂ́A܂̖s܂B + +^Cgɏiɂ́Ã^Cgɉ҂Ă邩‚oĂB + +グ𓾂ɂ́AŕȂB + +Ȃv[V̊߂Ă悤ɊAȂ̏iɘbĂBi邽߂ɉKv̂??𖾎Iɐq˂āA낤Ƃ܂B͔nĂ܂A΂΂ȂKv邱Ƃɑ΂邠Ȃ̔F́AȂ̏iƂ͂ȂقȂł傤B܂A͂‚̓_łȂ̏is~߂܂B + +قƂǂ̃vO}́A炭炩̌`őΓIȔ\͂̌֒ꂽoĂł傤Bǂ̂ƂAׂĂgbv10ɓ킯ł͂܂IA͐^ɕ]ĂȂlXĂ܂B݂Ȃ̕]ɌɊSɃ}b`Ƃ͎vĂ܂񂪁A͐lXTēKxɌłƍlĂ܂BȂ̎dɖڂ邱ƂȂ]邱Ƃ͂ł܂BƂɂ́ARlIȏK̂߂ɁANɋCtȂƂ܂B瑽̎dA`[inIɗĂƁA͓ɍɂȂ܂B + +Next [Serving Your Team - How to Develop Talent](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/jp/3-Advanced/README.md b/jp/3-Advanced/README.md new file mode 100644 index 0000000..85d0b2e --- /dev/null +++ b/jp/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. Advanced +[//]: # (Version:1.0.0) +- Technological Judgment + - [How to Tell the Hard From the Impossible](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [How to Utilize Embedded Languages](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Choosing Languages](Technical-Judgment/03-Choosing-Languages.md) +- Compromising Wisely + - [How to Fight Schedule Pressure](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [How to Understand the User](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [How to Get a Promotion](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- Serving Your Team + - [How to Develop Talent](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [How to Choose What to Work On](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [How to Get the Most From Your Team-mates](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [How to Divide Problems Up](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [How to Handle Boring Tasks](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [How to Gather Support for a Project](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [How to Grow a System](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [How to Communicate Well](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [How to Tell People Things They Don't Want to Hear](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [How to Deal with Managerial Myths](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [How to Deal with Organizational Chaos](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/jp/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md b/jp/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md new file mode 100644 index 0000000..d195d4f --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -0,0 +1,23 @@ +# How to Develop Talent + +Nietschze͔ނ[Stronger]ƌƂɌ֒F + +>j󂵂Ȃ̂́A苭܂B + +Ȃ̍ő̐ӔC͂Ȃ̃`[łBȂ͂ꂼ̂Ƃ悭mĂ͂łBȂ͂Ȃ̃`[L΂ׂłAނɕSׂł͂܂BȂ͒ʏAނ炪LтĂ@ɂ‚ĘbׂłBނ炪𔃎΁Aނ͂܂@Â܂BevWFNgA܂ׂ͑̂ẴvWFNgŁAĂ@ƂɓK@ŃXgb`s܂B葽̎d^邱Ƃł͂ȂAނɐVXL^A`[ŐVʂ肷邱ƂɂāAނL΂B + +ȂgiȂg܂ށjXs悤ɂāAȂ̃XPW[ʼn炩̎sv悷ׂłBĎsȂ΁A`͂܂BXs邱ƂȂ΁AȂ͏\Ɋ撣Ă킯ł͂܂BNsƁÂ悤Ɉ킸ɁAł邾₩ɂׂłB + +e`[̃o[wA@tĂ悤ɂĂBłȂꍇ́Aނ炪܂@ÂĂKv邱Ƃ𖾊mɂꂼꎿ₵ĂBȂ͂ŝ܂܂ɂȂ΂ȂȂ܂񂪁A݂Ȃ]ނ̂mĂׂłB + +ႢmCŝ߂ɕׂ𕪒SĂȂl߂邱Ƃ͂ł܂BȂ͂܂@ÂĐYIɂ悤ɓw߂Ȃ΂Ȃ܂BȂEϗ͂ĂAێĂBȂ̔EςꂽAĂBӐ}IɃxčƂĂĺA`[ɂƂČł͂Ȃ߁A`[Ɏc葱邱Ƃ͂ł܂B + +Ȃ̃`[̋łȃo[ɁAނMĂ邱ƂAɘbƂŖmɂ܂B^͌RƔᔻvCx[gɂKv܂B + +`[̋o[́ARA`[̎アo[dł傤B͊SɎRȂƂłANꐶANɂĎז邱Ƃ͂܂B + +ǂvO}10l̈vO}Ŷ́AɔfȂƂȎłB͊ȏ󋵂o܂BȂ̎アvO}ƎזɂȂꍇ́AȂ葬Ƃł邱Ƃ͂΂ΐ^łBȂꍇAȂ͎ۂɒZԂłƐi𐋂ł傤BAȂ́̕Aアo[̌PA̒m̕yAċ͂ȃo[̑r񕜂\͂ƂA‚̏dvȗ_܂B̓_ŋȂ΂Ȃ炸A͂pxlȂ΂Ȃ܂B + +Ȃ͂΂΁A苭`[o[ɒIłAӐ[`ꂽ^XN^邱Ƃł܂B + +Next [How to Choose What to Work On](02-How-to-Choose-What-to-Work-On.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md b/jp/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md new file mode 100644 index 0000000..e192525 --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -0,0 +1,5 @@ +# How to Choose What to Work On + +̃j[Yƃ`[̃j[YƂ̃oXāAǂ̂悤ȑʂ̃vWFNgƂ邩I܂B Ȃ͎ԍDȂƂȂ΂Ȃ܂񂪁A葽̎d̂ł͂ȂAVXLsgĎgL΂@‚悤Ƃ܂B [_[VbvƃR~jP[VXL͋ZpXLdvłB Ȃɋ΁AvWFNgł́AXN炷߂ɁAł邾AłȁA܂̓XN̍^XNsĂB + +Next [How to Get the Most From Your Team-mates](03-How-to-Get-the-Most-From-Your-Teammates.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md b/jp/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md new file mode 100644 index 0000000..f6b14e9 --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -0,0 +1,15 @@ +# How to Get the Most From Your Team-mates + +`[CgőɊpɂ́A`[̐_𖁂AׂĂ̐llIɒ킵AlIɊւ葱悤ɂĂB + +`[̐_𔭒B邽߂ɁAS̈ߕp[eB[̂悤ȖȂ̂͗ǂ̂́AlIȑhƓ炢ǂ̂ł͂܂BN̐l𑸏dĂȂANN_Ȃł傤B`[̐_́AlX`[̂߂ɋ]𕥂āǍlIȗv̑OɃ`[̗ǂ̊ϓ_lƂɍ܂Bw҂ƂāAȂ͂̓_Ŏ߂邱Ƃ͂ł܂B + +`[[_[Vbv̌1‚́ASoCCOł悤ɃRZTX𑣐i邱ƂłB́A`[CgԈĂ邱ƂXӖ܂B‚܂AꂪvWFNg܂ɂQ邱ƂȂ΁ARZTXɊÂĎ̃`[̉lƎ̂悤ɂȂ΂Ȃ܂BꂪNAӂȂłBPɌRƔ΂AӂɓӂĂB‚AĂ悤ɕ肵Ă͂܂BȂӌɓӂĂȂƌ܂A`[̃RZTXdvƍlĂB͂΂Δނɋt߂肳܂Bނ炪t߂肵ꍇAނ炪ŏ̌vʉ߂Ǝ咣ȂłB + +K؂ȑc_ɓӂȂlꍇ́APɌKvƎ咣AꂪȂ̌łƎ咣܂BȂ̌肪ԈĂ邩ǂ𔻒f@ꍇA܂͂ꂪԈĂ邱ƂŎꂽꍇ́Ał邾؂ւāAlFĂB + +Ȃ̃`[ɂ́AO[vƂÕʂɂA`[Xsbg𐶂ݏoAʓIȃ`[邽߂ɍlĂ邱Ƃq˂ĂB + +ґł͂Ȃpɂɏ܎^ĂBɂȂ܎^鎞ɂȂɓӂȂl܎^܂BɎ^AIɔᔻB 1‚̗OāFɂ͐⎸sׂ̐͌̌ɒpӂƂȂ܎^邱ƂłȂ̂ŁA̓vCx[gŏ܎^ׂłB + +Next [How to Divide Problems Up](04-How-to-Divide-Problems-Up.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md b/jp/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md new file mode 100644 index 0000000..6ebb2b7 --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -0,0 +1,9 @@ +# How to Divide Problems Up + +\tgEFAvWFNg𗘗pāAlɂĎs^XNɕ̂͊yƂłB͑ɍsKv܂Bɂ́A}l[W[́AƂsllɌςsƂłƍlĂ邱Ƃ܂B͌l̐YɈقȂ邽ߕs”\łBR|[lgɂ‚Ă̓̒mĂĺAɕωAptH[}Xɑ傫ȉe^邱Ƃł܂B + +ȉƂ́AtỷF^ĨR[`eI݂̋lĂ悤ɁAoLxȃ`[[_[́AʏAvWFNg̕`[̎dɕ邱Ƃ͂ł܂񂻂炪蓖Ă郁o[B́A\̃`[󂵂Ă͂ȂȂR̈ꕔłB + +́AlX݂̋\zA_PAVXLw񂾂肵đދ悤ɂȂƂAx̊댯܂BA含́AߓxɎgpȂꍇɂ͔ɗLpȐYc[łB + +Next [How to Handle Boring Tasks](05-How-to-Handle-Boring-Tasks.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md b/jp/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md new file mode 100644 index 0000000..409e127 --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -0,0 +1,7 @@ +# How to Handle Boring Tasks + +ɂ́AЂvWFNg̐ɕsŒȑދȍƂ邱Ƃ͂ł܂B ̃^XŃAۂɂsKvl̎mC𑹂Ȃ”\܂B ɑΏ邽߂̍őP̕@́ALarry Wall̃vO}̑ӑĂ̔ĂяoA܂͑i邱ƂłB Rs[^ɂȂ̂߂̃^XNs邩A`[Cgŝ菕邽߂̉炩̕@‚悤Ƃ܂B ōŝ1TԂĂ܂dvO1TԓĂ̂́A苳IŁAɂ͔Ƃ傫ȗ_܂B + +ׂ̂Ăsꍇ́AދȍƂȂ΂ȂȂlɂ͎Ӎ߂܂AĈlōsƂ͂ł܂B Œł2l̃`[蓖ĂāAƂsASȃ`[[N𑣐iă^XN܂B + +Next [How to Gather Support for a Project](06-How-to-Gather-Support-for-a-Project.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md b/jp/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md new file mode 100644 index 0000000..079b83b --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -0,0 +1,5 @@ +# How to Gather Support for a Project + +vWFNg̃T|[gW߂ɂ́AgDŜɐ^̉lrW쐬ē`܂B Ȃ̃rW쐬ɑ̐lL悤ƂB ͔ނɂȂT|[g闝R^AȂ̃ACfẢb^܂B vWFNg̎vT|[^[•ʂɕW܂B ”\ȌAĂB ”\ł΁Ai⃂bNAbvăACfA𔭊ĂB vg^Cv͏ɋ͂łA\tgEFAł͐͂邩ɗDĂ܂B + +Next [How to Grow a System](07-How-to-Grow-a-System.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md b/jp/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md new file mode 100644 index 0000000..e3959ae --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -0,0 +1,23 @@ +# How to Grow a System + +؂̗tɂ͑l̃ACfA܂܂Ă܂Aľ`͂Sɂ͗Ă܂B󂪐B͑傫Ȃ܂Bl̂悤ɌA葽̗pr܂Bǂ͉ʎ𐶂݂܂B̌A͎ɁȂ̂͑̐ɉh{^܂B + +͂̂悤ȃ\tgEFAґ򂳂Ă܂B͂ł͂ȂBxr[ubW͂܂񂪁A̋͂܂BubW̓\tgEFA͂邩ɊȒPłB + +\tgEFAĂƍl邱Ƃ́AȐ_IȃC[W𓾂OɗLpȐi𐋂邱Ƃł̂ŁAǂlłB[U[̃tB[hobN𓾂āAgĐC邱Ƃł܂Bア葫؂邱Ƃ͌NłB + +vO}́AzĎgpł銮VXe݌vKv܂BAxȃvO}͂Ƒ̂ƂȂ΂ȂȂBVXeŏI鐬oH݌vKv܂BACfẢāAł邾X[YɗLpȐlHɕς铹‚̂͂Ȃ̎dłB + +sɂ́AŏIʂoAGWjAO`[Ă萋邱Ƃł@œ`BKv܂BAȂ͂܂Aނ炪ǂɂĂAǂɂĂ傫ȔĂȂƂɍsނɓ`Ȃ΂Ȃ܂B؂͐ĂȂ΂Ȃ܂B͈_Ŏł͂Ȃ炸Aŕ邱Ƃ͂ł܂B + +̃Av[`́AɓWJĂ܂B邱Ƃ̂Ȃ}CXg[́AoHɉĐi}[N邽߂Ɏgp܂BIȃrWlX‹ł́AƂ݌vꂽGh|Cg牓ĂĂA}CXg[[XAł邾vグ邱ƂőP̕@łBvO}[̎d1‚́A}CXg[ŕ\ꂽoHɑI邱ƂɂāA̕VƏ̕ṼoXƂ邱ƂłB + +iIȃvO}́A\tgEFAA`[Aѐl𑝂₷Ƃ3‚̐ӔC𕉂Ă܂B + +ǎҁARob HaferniḱÃZNV̂̃RgŁASɈp܂Ƃ͂łȂF + +>͂ȂŏdvĂƎvB̓VXełȂAASYA[U[C^[tFCXAf[^fȂǂłBȂ傫ȖڕWB邽߂ɑK͂ȃVXeɎgނ悤ɂȂƁA΂ɏdvłBIɋ߂ÂAׂĂ傤ǂ܂ȂƂ𔭌Ƃʂȋ|قLjȂi[҃j[XVXe̍ŋ߂̑厸sĂjB͂ɐiŁAR̖@ƌĂ܂BK͂ŕGȃVXe̓[邱Ƃ͂ł܂BPȃVXeÄӐ}IȃXebvŕGȃVXeɂił܂B + +ǂɕԐM邱Ƃł܂H* Fiat lux *I + +Next [How to Communicate Well](08-How-to-Communicate-Well.md) diff --git a/jp/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md b/jp/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md new file mode 100644 index 0000000..e79706c --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -0,0 +1,11 @@ +# How to Communicate Well + +܂R~jP[Vɂ́AꂪǂقǓFȂ΂Ȃ܂B͂ꎩg̃XLłBȂR~jP[VȂ΂ȂȂlɌׂƂɂāA͂荢ɂȂBނ͂Ȃ𗝉邱ƂɔMSɓĂ܂Bނ͕nɘbAnɏBނ͂΂ΉߘJ܂͑ދłAŒłȂgł傫Ȗł͂ȂA̎dɑWĂ܂BƂuAMAAH邱Ƃ̗_1‚́A܂΁A肪ǂɂ̂Aǂ̂悤ɒ̂ȒPɒm邱ƂłƂƂłB + +vO}[͐c肪ޏ̃`[Ƃ̃R~jP[VɈˑЉIȓłBxȃvO}[́Axޏ̃`[O̐lXƂ̃R~jP[VɈˑЉIȓłB + +vO}[͍疽߂o܂Bs1‚̋[@́A`[Ỏ炩̒ĂJn邱ƂłB́A* strawman *܂* white-paper *`ŁA܂͌ł̂ݍsƂł܂B̃[_[Vbv́Ac_̏ݒ肷Ƃ傫ȗ_܂B͂Ȃᔻɂ炵AɈƂɁAƖ\I܂BxȃvO}́AƓ̗͂Ă邽ߓƎ̐ӔĈŁA󂯓鏀łĂKv܂BvO}[ł͂ȂNƉƂ́A‚̓_Ń[_[Vbv񋟂vO}[KvƂĂ܂BvO}[́AɗĂACfAƃAeB̋n̈ꕔłB + +͂܂R~jP[V}X^[ł܂łAݎgł̂́A4‚̃Av[`ƂĂƎv܂B̃ACfAɏA͌ŘbÁiۂ̎ɂdqIɂjfāÃvZXhJԂB͂̎̓R~jP[Vł́Ax\ɐhȂƎv܂BȂ̃ACfAɎ󂯓ȂȂAȂ͗_Ă͂܂Bނ̏ɃGlM[𓊓ꍇANȂ̂߂ɂnゾƂ͎vȂł傤B + +Next [How to Tell People Things They Don't Want to Hear](09-How-to-Tell-People-Things-They-Don't-Want-to-Hear.md) diff --git a/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Don't-Want-to-Hear.md b/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Don't-Want-to-Hear.md new file mode 100644 index 0000000..f294f5c --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Don't-Want-to-Hear.md @@ -0,0 +1,9 @@ +# How to Tell People Things They Don't Want to Hear + +Ȃ͂΂΁AlXɕs^悤ȂƂ`Kv܂BȂ炩̗RłĂ邱ƂYȂłBɂ‚ĉłȂꍇłAł邾`Ă̂ŁAނ͏\ȏ𓾂܂B + +Nɖ`ŗǂ̕@́Aɉ񎦂邱ƂłB̍őP̕@́Ȁ؂ĔނɃAs[邱ƂłBMȂ댯ꍇ́AȂ̎咣̎xW߂ׂłB + +ȂȂ΂ȂȂłsňʓIȂƂ̈‚́Aނ̃XPW[ԈĂȂ΂ȂȂƂƂłBǐSIȃvO}[́Â͌łAł邾Ȃ΂Ȃ܂BB̃ANVNɂłm点邱ƂłĂA}CXg[ƂɃANVƂ͂܂Bsɂ́A??IɂłȂĂAȂƂ_Iɂ̓`[ƂčsǂłBȂĂꏊƂɂ‚ĉł邩̗łȂ̃`[̓͂]ނł傤B`[͂Ȃɉe^Ȃ΂Ȃ܂B + +Next [How to Deal with Managerial Myths](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md b/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md new file mode 100644 index 0000000..9ce4532 --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -0,0 +1,9 @@ +# How to Tell People Things They Don't Want to Hear + +���Ȃ��͂��΂��΁A�l�X�ɕs�������^�����悤�Ȃ��Ƃ��`�����K�v�������܂��B���Ȃ������炩�̗��R�ł��������Ă��邱�Ƃ��Y���Ȃ��ł��������B�����ɂ‚��ĉ����ł��Ȃ��ꍇ�ł��A�ł��邾���������������`���Ă����̂ŁA�ނ��͏\���ȏ����𓾂����܂��B + +�N���ɖ������`�����ŗǂ̕��@�́A�����ɉ��������񎦂��邱�Ƃł��B�����̍őP�̕��@�́A�����̏������؂��Ĕނ��ɃA�s�[�����邱�Ƃł��B�M�������Ȃ��댯�������ꍇ�́A���Ȃ��̎咣�̎x�����W�߂��ׂ��ł��B + +���Ȃ��������Ȃ����΂Ȃ��Ȃ��ł��s�����ň��ʓI�Ȃ��Ƃ̈��‚́A�ނ̃X�P�W���[�����Ԉ����Ă��Ȃ����΂Ȃ��Ȃ��Ƃ������Ƃł��B�ǐS�I�ȃv���O���}�[�́A�����������̂͌��ł����A�ł��邾�����������Ȃ����΂Ȃ��܂����B�B���̃A�N�V�������N�ɂł��m�点�邱�Ƃł����Ă��A�}�C���X�g�[�����������Ƃ��ɃA�N�V���������������������������Ƃ͂����܂����B�������s���ɂ́A����??�I�ɂłȂ��Ă��A���Ȃ��Ƃ����_�I�ɂ̓`�[���Ƃ��čs�������ǂ��ł��B���Ȃ��������Ă����ꏊ�Ƃ����ɂ‚��ĉ����ł��邩�̗����ł��Ȃ��̃`�[���̓��͂��]�ނł��傤�B�`�[���͂��Ȃ��ɉe�����^���Ȃ����΂Ȃ��܂����B + +Next [How to Deal with Managerial Myths](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/jp/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md b/jp/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md new file mode 100644 index 0000000..8a4d9ca --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -0,0 +1,13 @@ +# How to Deal with Managerial Myths + +* myth *Ƃt͎ɂ̓tBNVӖ܂B͂[Ӗ܂B͂܂AFƐlނƂ̊֌W@IӖ̕Ӗ܂B}l[W[́AvO}[ƂĊw񂾂ƂYāA̐_bMX܂B̐_bUł邱ƂM悤Ƃ͖̂ł莸sĂł傤B̂߁AȂ͂̐MO_bƂĔFׂłF + +- 葽̃hLgɗDĂ܂B iނ͂ꂪ~A‚łȂɔ₷Ƃ]łȂBj +- vO}͓ɂ邱Ƃł܂B ivO}͌ႢɈقȂj +- Xs[hAbv邽߂ɁA\[X㔼̃vWFNgɒlj邱Ƃł܂B iVlƂ̃R~jP[ṼRXǵAɂȂقƂǏɉېł܂Bj +- \tgEFAJmɌς邱Ƃ”\łB i_Iɂ”\ł͂܂Bj +- vO}̐ÝAR[hŝ悤ȒPȃgbN̊ϓ_瑪ł܂B iȌ͂ł΁AR[hs͈AǂƂł͂܂Bj + +@΁ÂƂ邱Ƃ͂ł܂AĂȂƈCɂȂ炸A̐_bɑ΍RĂȂ̕]𑹂ȂƂ͂܂B̐_b̂ꂼ́ANĂ邩ۂɎxzĂ}l[W[̍l߂B^́A}l[W[ނ炪ǂΗeՂɂȂAނ炪ꍇɂ͂W邱ƂłB + +Next [How to Deal with Organizational Chaos](11-How-to-Deal-with-Organizational-Chaos.md) \ No newline at end of file diff --git a/jp/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md b/jp/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md new file mode 100644 index 0000000..5f6967b --- /dev/null +++ b/jp/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md @@ -0,0 +1,11 @@ +# How to Deal with Organizational Chaos + +CItAoCAEgAiposA΁AV̗pȂǂ̂悤ȁAgDI̒ZԂ΂΂܂B͊FɂƂĕsłAlIȎS؂Ă̂ł͂ȂA\͂ŐݗꂽvO}[ɂƂĂ͂炭słBgD̍́AvO}ɂƂĖ@̗͂𔭊D̋@łB͐[̔閧ł邽߁AŌɕۑ܂BȂvO}[łȂ΁AǂłĂB + +>GWjA͑n͂Ǝ͂Ă܂B + +mGWjA͈ʂ̃\tgEFAЂł́AGWjAʓIɐi̔ArWlXʓIɊǗ邱ƂłȂ߁AGWjAȂʼn쐬Ĉێ邱Ƃ͂ł܂B̔\͂́AꎞIȑgDɊ֘AقƂǂׂĂ̖ɑ΂ė؂̂łBȂĂƂASɖāANĂȂ̂悤ɑׂłBȂ͂Aق邩܂񂪁AN΁A炭͂̂߂ɐVd𓾂邱Ƃł܂BʓIɂ́A@̗͂ĂȂXgX̑lȂ̗̂ɓāAȂɉ΂Ƃ悤ɂȂ܂BȂ{ɂꂪnƊmMĂȂ΁Aނ炪܂Ŕ΂̂ԂłB + +Ȃ[_[ł΁AƂ𑼂̐lbƂ𖳎悤ɐlXɓ`܂B̍s[úAlIɂ͍ō̂̂łAȂ̉ЂvWFNgɍœKłB + +Next [Glossary](../../GLOSSARY.md) diff --git a/jp/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/jp/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..080cfba --- /dev/null +++ b/jp/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# How to Tell the Hard From the Impossible +[//]: # (Version:1.0.1) +ƂāAs”\ƌȂ͎̂̎dłBقƂǂ̍ƃvO}[̊ϓ_́APȃVXe琬łȂAłȂꍇ͕s”\łB̒`ɂāAƌĂ΂͕̂s”\łBʂ̒PȂd͓AKs”\Ƃ킯ł͂ȂB + +ȊwIȊϓ_\tgEFAHẘϓ_́Aۂɂ͕s”\ȂƂɂ܂Ă邩Ȃ̂ŁA̋ʂ͖ʔȂB͋NƉƂPȂ鍢łAނ炪]ނ̂̂قƂǂ𓾂鍇Iȉ‚̂邠Ȃ̎dɂȂ܂B́AMăXPW[AXNĂꍇɂ͓łB + +ł͓IȔ^FvZVXeȂǁARƂv𖞂Ƃ͕s”\łBvNɂ邱Ƃł΁Al̖͓IȔ^ƐFvZAvr[ύXÃX^CɊÂČڋqx߂āÂ҂VXe\z܂傤B̑NȒ`ȂAȂ͐܂B + +Next [How to Utilize Embedded Languages](02-How-to-Utilize-Embedded-Languages.md) diff --git a/jp/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md b/jp/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md new file mode 100644 index 0000000..717a912 --- /dev/null +++ b/jp/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -0,0 +1,11 @@ +# How to Utilize Embedded Languages + +vO~OVXeɑgݍނƂ́AvO}[ɂƂĂ͂قƂǃG`bNȖ͂Ă܂B͎słłnIȍsׂ1‚łB̓VXeɋ͂ɂ܂Bޏ͔ޏ̍łnIȃveEX̃XL𔭊邱Ƃł܂B͂Ȃ̗FlɃVXeB + +E̍ō̃eLXgGfB^ɂ́AׂČꂪgݍ܂Ă܂B́AړI̎҂Kł͈͂Ŏgpł܂BA̎gṕAeLXgGfB^̂悤ɃIvVōsƂł܂B̂߁ACjVA`u͂gpłANgp邱Ƃ͂ł܂B + +Ƒ̑̃vO}[́AړȊgݍ݌쐬Ƃ㩂ɊׂĂ܂B͂ɓxBłɑgݍ݌ɓĐ݌vꂽ̌ꂪ݂܂BȂ͐V̂OɓxlȂ΂Ȃ܂B + +𖄂ߍޑOɎgɐq˂ׂ^̎́A͎̒O̕ƈꏏɁA܂͔΂ɓ̂ł傤HȂOvO}[ȊO̐lɌ肵悤ƎvAǂ΂ꂪɗ܂HȂ̈Ӑ}I[fBGXvO}łꍇAނ̓AvP[VvO}C^tF[XiAPIjDނł傤H͂ǂȌłHvO}[́AgĂVwԂƂ]܂ȂBނ̕ƗݍƁAwԂ̂ɑ̎Ԃ₷Kv͂܂BV쐬邱Ƃ͊тłBA͂[U[̃j[YɖӖړIɂׂł͂܂BȂ{Ɍ̃j[YƃACfAĂȂǍgpāA[U[ɎĂgꂽ̂pł悤ɂ܂傤B + +Next [Choosing Languages](03-Choosing-Languages.md) \ No newline at end of file diff --git a/jp/3-Advanced/Technical-Judgment/03-Choosing-Languages.md b/jp/3-Advanced/Technical-Judgment/03-Choosing-Languages.md new file mode 100644 index 0000000..c626ff6 --- /dev/null +++ b/jp/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -0,0 +1,15 @@ +# Choosing Languages + +ނ̎dinbJ[jǓƂȃvO}[́A^XN̂߂̍ŗǂ̌IԂƂł܂BقƂǂ̍ƃvO}[́Agp錾قƂǐł܂BʓIɁÁ̖AZpIȌł͂ȂIȌĂ擱IȏiɂČ肳ĂA΂Βڂ̒mŁA܂󂯓ĂȂc[mĂƂłAōłB̏ꍇɂ́A`[Ԃ̒c̐^̉b́AxR~jeB̑傫ɂāAl̑Ir܂B̏ꍇA}l[W[́Ǎł̌oƒvO}[قKv邱ƂɌ܂BԈႢȂAނ̓vWFNgƂɂƂčőP̗vƔFĂ̂񋟂ĂA𑸏dȂ΂Ȃ܂BA͌lIɂ́AꂪȂ”\̍łʂŌʂ̗KłƌlIɐMĂ܂B + +A͌Ĉꎟł͂܂BRAꂪ`tĂĂAȂ̃Rg[͈̔͂𒴂ĂĂAc[⑼̃vOʂ̌ŏȂ΂ȂȂꍇ܂Bꂪߍ܂ꍇi܂AɍlKv܂jȂI̓[U[̕ɑ傫ˑ܂BdɍłKgpĉЂvWFNgɃT[rX񋟂Adʔ邽߂ɁA𗘗pKv܂B + +vO~ÓARwԂقǓȂƂ_ŁAۂɂ͕\L@ƌĂ΂ׂłBS҂ꕔ̊O̐lɂ͐VwԂ͓̂ƂłBȂ̃xg̉3‚̃xgƁA͎ۂɗp”\ȃCuɊ邽߂̖ɉ߂܂B 1‚́A3‚܂4‚̌ŃR|[lgĂ悤ȑ傫ȃVXelX܂B̂悤ȃVXéȀꍇA1‚̌VXe‚̓_ł苭͂łƎ咣Ă܂B + +- قȂ\L@ŋLqĂR|[lgԂɂ́AKRIɑa݂܂iAꂢȃC^tF[Xł͂Ȃ܂jB +- eR|[lg•ʂɏƂŁAV/vbgtH[ɊȒPɐi邱Ƃł܂B +- 1‚̌ꂪVXeŜɓKĂȂ”\܂BW[ɕ̌gp邱ƂŁAK؂ȃc[IԂƂł܂B + +̉ëꕔ͐SwIȂ̂ɉ߂Ȃ܂BSw͏dvłBǂ̂ƂAꐧ`̔p͂ꂪ񋟂闘_dvłB + +Next [Compromising Wisely - How to Fight a Schedule Pressure](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/jp/5-Bibliography.md b/jp/5-Bibliography.md new file mode 100644 index 0000000..e96590e --- /dev/null +++ b/jp/5-Bibliography.md @@ -0,0 +1,31 @@ +# Appendix A - Bibliography/Websiteography +[//]: # (Version:1.0.0) +## Books + +[Rules00] Guy Kawasaki, Michelle Moreno, and Gary Kawasaki. 2000. HarperBusiness. Rules for Revolutionaries: The Capitalist Manifesto for Creating and Marketing New Products and Services. + +[RDev96] Steve McConnell. 1996. Microsoft Press. Redmond, Wash. Rapid Development: Taming Wild Software Schedules. + +[CodeC93] Steve McConnell. 1993. Microsoft Press. Redmond, Wash. Code Complete. + +[XP99] Kent Beck. 1999. 0201616416. Addison-Wesley. Extreme Programming Explained: Embrace Change. + +[PlanXP00] Kent Beck and Martin Fowler. 2000. 0201710919. Addison-Wesley. Planning Extreme Programming. + +[Prag99] Andrew Hunt, David Thomas, and Ward Cunningham. 1999. 020161622X. Addison-Wesley. The Pragmatic Programmer: From Journeyman to Master. + +[Stronger] Friedrich Nietzsche. 1889. Twilight of the Idols, "Maxims and Arrows", section 8.. + +## Web Sites + +[PGSite] Paul Graham. 2002. Articles on his website: [http://www.paulgraham.com/articles.html](http://www.paulgraham.com/articles.html). All of them, but especially "Beating the Averages". + +[Hacker] Eric S. Raymond. 2003. How to Become a Hacker. [http://www.catb.org/~esr/faqs/hacker-howto.html](http://www.catb.org/~esr/faqs/hacker-howto.html). + +[HackDict] Eric S. Raymond. 2003. The New Hacker Dictionary. [http://catb.org/esr/jargon/jargon.html](http://catb.org/esr/jargon/jargon.html). + +[ExpCS] Edsger W. Dijkstra. 1986. How Experimental is Computing Science?. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF). + +[Knife] Edsger W. Dijkstra. 1984. On a Cultural Gap. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF). + +Next [History](6-History.md) \ No newline at end of file diff --git a/jp/6-History.md b/jp/6-History.md new file mode 100644 index 0000000..4a46e40 --- /dev/null +++ b/jp/6-History.md @@ -0,0 +1,47 @@ +# Appendix B - History +[//]: # (Version:1.0.0) +## Move to Github + +This essay has been created as a repository on Github so that it can be easily shared, updated and improved. It was copied from [http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm) by [Braydie Grove](https://github.com/braydie). It was moved to Github in January 2016. + +## Request for Feedback or Extension + +Please send me any comments you may have on this essay. I consider all suggestions, many of which have already improved this essay. + +I have placed this essay under the GNU Free Documentation License. This license is not specifically designed for essays. Essays are usually intended to be coherent and convincing arguments that are written from a single point of view in a single voice. I hope this essay is a short and pleasant read. + +I also hope that it is instructive. Although not a textbook, it is broken into many small sections to which new sections can be freely added. If so inclined, you are encouraged to expand upon this essay as you see fit, subject to the provisions of the License. + +It may be arrogance to imagine that this document is worthy of extension; but hope springs eternal. I would be joyous if it were extended in the following ways: + +The addition of a comprehensive reading list to each section, + +The addition of more and better sections, + +Translation into other languages, even if only on a subsection-by-subsection basis, and/or + +Criticism or commentary in-lined into the text. + +The ability to build into different formats, such as palm formats and better HTML. + +If you inform me of your work, I will consider it and may include it in subsequent versions that I produce, subject to the provisions of the License. You may of course produce your own versions of this document without my knowledge, as explained in the License. + +Thank you. + +Robert L. Read + +## Original Version + +The original version of this document was begun by Robert L. Read in the year 2000 and first published electronically at Samizdat Press(http://Samizdat.mines.edu) in 2002. It is dedicated to the programmers of Hire.com. + +After this article was mentioned on Slashdot in 2003, about 75 people sent me email with suggestions and errata. I appreciate them all. There was a lot of duplication, but the following people either made major suggestions or were the first to find a bug that I fixed: Morgan McGuire, David Mason, Tom Moertel, Ninja Programmer (145252) at Slashdot, Ben Vierck, Rob Hafernik, Mark Howe, Pieter Pareit, Brian Grayson, Zed A. Shaw, Steve Benz, Maksim Ioffe, Andrew Wu, David Jeschke, and Tom Corcoran. + +Finally I would like to thank Christina Vallery, whose editing and proofreading greatly improved the second draft, and Wayne Allen, who encouraged me to initiate this. + +## Original Author's Bio + +Robert L. Read lives in Austin, Texas, with his wife and two children. He is currently a Principal Engineer at Hire.com, where he has worked for four years. Prior to that he founded 4R Technology, which made a scanner-based image analysis quality control tool for the paper industry. + +Rob received a PhD from the University of Texas at Austin in 1995 in Computer Science related to database theory. In 1987 he received a BA in Computer Science from Rice University. He has been a paid programmer since the age of 16. + +Next [License](LICENSE.md) diff --git a/jp/7-Contributions.md b/jp/7-Contributions.md new file mode 100644 index 0000000..a9482ca --- /dev/null +++ b/jp/7-Contributions.md @@ -0,0 +1,34 @@ +# Contributions +[//]: # (Version:1.0.0) +This repository aims to be a community driven project, and your involvement will ultimately help improve the quality of this guide. + +## What can I do to contribute? +There are a number of ways to contribute to "How to be a Programmer". + +- Ideas for new sections +- Improvements to existing sections +- Identifying typos or other issues in sections +- Contributing additional links to resources for sections +- General suggestions for improving the project +- Provide translations of the guide + +## Translations + +Currently this guide has been translated from English into the following languages: + +- Chinese by [ahangchen](https://github.com/ahangchen) +- Russian by [paveltovchigrechko](https://github.com/paveltovchigrechko) +- Spanish by [Maximiliano Murua](https://gitlab.com/maximiliano.murua) + + +**If you provide the initial translation of the guide into another language, you become elegible to become a contributor on this project to help maintain and review changes made to the translation.** + +## Contributors + +Github holds a list of all [contributors](https://github.com/braydie/HowToBeAProgrammer/graphs/contributors) to this project. + +## Editorship and Move to GitHub + +[Braydie Grove](https://www.github.com/braydie) has agreed to serve as editor-in-chief. + +Braydie transposed the original essay into MarkDown and created the repository. diff --git a/GLOSSARY.md b/jp/GLOSSARY.md similarity index 94% rename from GLOSSARY.md rename to jp/GLOSSARY.md index c02bc64..283b316 100644 --- a/GLOSSARY.md +++ b/jp/GLOSSARY.md @@ -1,15 +1,11 @@ # Glossary - +[//]: # (Version:1.0.0) This is a glossary of terms as used in this essay. These do not necessarily have a standardized meaning to other people. Eric S. Raymond has compiled a massive and informative glossary[HackerDict] that rather surprisingly can pleasurably be read cover-to-cover once you can appreciate a fraction of it. ### unk-unk Slang for unknown-unknown. Problems that cannot presently even be conceptualized that will steal time away from the project and wreck the schedule. -### boss - -The person or entity that gives you tasks. In some cases this may be the public at large. - ### printlining The insertion of statements into a program on a strictly temporary basis that output information about the execution of the program for the purpose of debugging. @@ -42,10 +38,6 @@ Big improvements that cost little. The initiator of projects. -### garbage - -Objects that are no longer needed that hold memory. - ### business A group of people organized for making money. @@ -80,7 +72,7 @@ Memory can be said to be heap allocated whenever the mechanism for freeing it is ### garbage -Allocated memory that no longer has any useful meaning. +Memory which is being taken up by objects your application no longer needs. ### garbage collector @@ -140,4 +132,4 @@ A document meant to be the starting point of a technical discussion. A strawman ### white-paper -An informative document that is often meant to explain or sell a product or idea to an audience different than the programmers of that product or idea. \ No newline at end of file +An informative document that is often meant to explain or sell a product or idea to an audience different than the programmers of that product or idea. diff --git a/jp/LICENSE.md b/jp/LICENSE.md new file mode 100644 index 0000000..3e18a1a --- /dev/null +++ b/jp/LICENSE.md @@ -0,0 +1,12 @@ + +## Creative Commons Attribution Share-Alike + +"How To Be A Programmer: Community Version" by Robert L. Read with Community is licensed under Creative Commons Attribution Share-Alike Internal v 4.0. + +At present this work will be edited by Braydie Grove and Robert L. Read. + +We will make reasonable attempts to maintain proper attributions of contributions in the section entittle "Contributions". If you make a pull-request with a significant contribution, please add a very brief description of your contribution to that section. + + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/jp/README.md b/jp/README.md new file mode 100644 index 0000000..965ddd7 --- /dev/null +++ b/jp/README.md @@ -0,0 +1,103 @@ +# How to be a Programmer: Community Version +[//]: # (Version:1.0.0) +Robert L. Read with Community + +Copyright 2002, 2003, 2016 Robert L. Read + +Licensed under [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +## はじめに +良いプログラマになることは難しく、高貴です。ソフトウェアプロジェクトの実質的なビジョンを実現する最も難しい部分は、同僚や顧客を扱うことです。コンピュータプログラムを書くことは重要であり、優れた知性とスキルを必要とします。しかし、実際に子供の遊びであるのは、良いプログラマが、顧客と部分的に責任がある無数の同僚の両方のために成功するソフトウェアシステムを作るために必要なことです。このエッセイでは、21歳のときに誰かが私に説明したかったことを可能な限り簡潔にまとめようとしています。 + +これは非常に主観的なものであり、したがって、この論文は個人的で、多少の意見をもって運命づけられます。私はプログラマが自分の仕事で直面しなければならない可能性が高い問題に自分自身を限定しています。これらの問題の多くとその解決策の多くは人間の状態に非常に一般的なものであり、おそらく私は説得力があるように見えます。それにもかかわらず、私はこのエッセイが役立つことを願っています。 + +コンピュータプログラミングはコースで教えられます。優れた本:Pragmatic Programmer [Prag99]、Code Complete [CodeC93]、Rapid Development [RDev96]、Extreme Programming Explained [XP99]はすべてコンピュータプログラミングと優れたプログラマーであるという大きな問題を教えています。ポール・グラハム(PGSite)とエリック・レイモンド[ハッカー]のエッセイは、この記事の前に、またはこの記事とともに読むべきです。このエッセイは、社会問題を強調し、必要なスキル全体を包括的に要約することによって、それらの優れた作品とは異なります。 + +このエッセイでは、ボスという言葉は、あなたがするプロジェクトを提供する人を指すのに使用されます。私はビジネス、会社、部族という言葉を同義語として使っていますが、ビジネスはお金を抱くことを暗示しますが、会社は現代の職場を暗示し、部族は一般的にあなたが忠誠心を分かち合う人々です。 + +部族へようこそ。 + +## Contents + +1. [Beginner](1-Beginner) + - Personal Skills + - [Learn to Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [How to Remove an Error](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [How to Optimize Loops](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [How to Manage Memory](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - Team Skills + - [Why Estimation is Important](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [How to Find Out Information](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [How to Document Wisely](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [How to Work with Poor Code](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [How to Use Source Code Control](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [How to Unit Test](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [Intermediate](2-Intermediate) + - Personal Skills + - [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [How to Stress Test](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Learn to Type](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Communication Languages](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [How to analyze data](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - Team Skills + - [How to Manage Development Time](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [How to Manage Consultants](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - Judgment + - [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [How to Grow Professionally](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [Advanced](3-Advanced) + - Technological Judgment + - [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - Compromising Wisely + - [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [How to Understand the User](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - Serving Your Team + - [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [How to Grow a System](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [Glossary](GLOSSARY.md) +5. [Appendix A - Bibliography/Websiteography](5-Bibliography.md) +6. [Appendix B - History (As of January 2016)](6-History.md) +6. [Appendix C - Contributions (As of January 2016)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/jp/SUMMARY.md b/jp/SUMMARY.md new file mode 100644 index 0000000..e442482 --- /dev/null +++ b/jp/SUMMARY.md @@ -0,0 +1,80 @@ +# Summary +[//]: # (Version:1.0.0) +* [Beginner](1-Beginner/README.md) + * Personal Skills + * [Learn to Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + * [How to Debug by Splitting the Problem Space](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + * [How to Remove an Error](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + * [How to Debug Using a Log](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + * [How to Understand Performance Problems](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + * [How to Fix Performance Problems](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + * [How to Optimize Loops](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + * [How to Deal with I/O Expense](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + * [How to Manage Memory](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + * [How to Deal with Intermittent Bugs](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + * [How to Learn Design Skills](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + * [How to Conduct Experiments](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + * Team Skills + * [Why Estimation is Important](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + * [How to Estimate Programming Time](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + * [How to Find Out Information](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + * [How to Utilize People as Information Sources](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + * [How to Document Wisely](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + * [How to Work with Poor Code](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + * [How to Use Source Code Control](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + * [How to Unit Test](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + * [Take Breaks when Stumped](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + * [How to Recognize When to Go Home](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + * [How to Deal with Difficult People](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +* [Intermediate](2-Intermediate/README.md) + * Personal Skills + * [How to Stay Motivated](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + * [How to be Widely Trusted](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + * [How to Tradeoff Time vs. Space](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + * [How to Stress Test](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + * [How to Balance Brevity and Abstraction](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + * [How to Learn New Skills](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + * [Learn to Type](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + * [How to Do Integration Testing](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + * [Communication Languages](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + * [Heavy Tools](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + * [How to analyze data](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + * Team Skills + * [How to Manage Development Time](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + * [How to Manage Third-Party Software Risks](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + * [How to Manage Consultants](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + * [How to Communicate the Right Amount](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + * [How to Disagree Honestly and Get Away with It](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + * Judgment + * [How to Tradeoff Quality Against Development Time](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + * [How to Manage Software System Dependence](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + * [How to Decide if Software is Too Immature](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + * [How to Make a Buy vs. Build Decision](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + * [How to Grow Professionally](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + * [How to Evaluate Interviewees](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + * [How to Know When to Apply Fancy Computer Science](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + * [How to Talk to Non-Engineers](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +* [Advanced](3-Advanced/README.md) + * Technological Judgment + * [How to Tell the Hard From the Impossible](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + * [How to Utilize Embedded Languages](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + * [Choosing Languages](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + * Compromising Wisely + * [How to Fight Schedule Pressure](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + * [How to Understand the User](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + * [How to Get a Promotion](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + * Serving Your Team + * [How to Develop Talent](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + * [How to Choose What to Work On](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + * [How to Get the Most From Your Team-mates](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + * [How to Divide Problems Up](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + * [How to Handle Boring Tasks](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + * [How to Gather Support for a Project](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + * [How to Grow a System](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + * [How to Communicate Well](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + * [How to Tell People Things They Don't Want to Hear](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + * [How to Deal with Managerial Myths](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + * [How to Deal with Organizational Chaos](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +* [Appendix A * Bibliography/Websiteography](5-Bibliography.md) +* [Appendix B * History (As of January 2016)](6-History.md) +* [Appendix C * Contributions (As of January 2016)](7-Contributions.md) diff --git a/ru/1-Beginner/Personal-Skills/01-Learn-To-Debug.md b/ru/1-Beginner/Personal-Skills/01-Learn-To-Debug.md new file mode 100644 index 0000000..a9fb4d2 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -0,0 +1,21 @@ +# Научитесь отлаживать +[//]: # (Version:1.0.0) +Отладка - это краеугольный камень профессии программиста. Основное значение слова "debug" это "устранять ошибки", но значение, которое имеет реальный вес, это "видеть, как исполняется программа, изучая ее код". Программист, который не умеет эффективно отлаживать, слеп. + +Те идеалисты, которые считают, что дизайн, анализ, теория сложности вычислений и подобное более фундаментальны, чем отладка, вряд ли являются работающими программистами. Работающий программист не живет в идеальном мире. Даже если вы идеальны, вы окружены и вынуждены работать с кодом, который написан в больших корпорациях, организациях вроде GNU и вашими коллегами. Большая часть этого кода неидеальна, и она неидеально задокументирована. Без способности видеть исполнение этого кода, малейший баг выбьет вас из колеи. Часто увидеть исполнение можно только с помощью эксперимента, то есть, отладки. + +Отладка больше касается исполнения программ, чем самих программ. Если вы купите программное обеспечение от большой компании, то, как правило, вам не доведется увидеть сам код. Но все равно будут моменты, когда программа не соответствует документации, либо документация просто ничего не говорит о конкретном поведении программы. Распространенный и яркий пример: сбой всей операционной системы во время работы программы. Обычно вы при работе создаете баг, изучаете собственный код и понятия не имеете, как он возник. Неизбежно это ведет к мысли о том, что вы делаете что-то не то, либо возникает некое обстоятельство, которое вы не учитываете в программе. Иногда трюк с изучением исходного кода помогает. Иногда нет, и тогда вы должны перейти к отладке. + +Чтобы понять, как исполняется программа, вы должны иметь возможность запустить ее и наблюдать за ее ходом исполнения. Иногда баг виден визуально, например, если он отображается на экране или между событиями в программе очевидна непредусмотренная задержка. Во многих других случаях, баг связан с факторами, которые нельзя наблюдать непосредственно, например, с состоянием переменных, конкретными строками кода, исполняющиеся в данный момент, либо с утверждениями внутри сложной структуры данных. Эти скрытые факторы надо выяснить. + +Распространенные методы изучения "внутренностей" программы можно поделить на: + +- Использование отладчика +- Вывод в консоль - внесение временных модификаций в программу, обычно выводящих информацию о ее текущем состоянии +- Логирование - создание постоянного интерфейса, который выводит ход исполнения программы в виде отчета + +Отладчики это прекрасное средство, когда они стабильны и доступны, но вывод в консоль и логирование гораздо важнее. Отладчики часто отстают от развития языков программирования, так что они могут быть доступны не в каждый момент времени. К тому же, некоторые отладчики могут незначительно изменять ход исполнения программы, поэтому применять их в этих случаях непрактично. Наконец, существуют виды отладки, такие как проверка утверждений в большой структуре данных, которые требуют написания нового кода и изменения хода исполнения программы. Так что важно знать, как пользоваться отладчиками, когда они доступны, но критично важно уметь использовать два оставшихся метода. + +Некоторые начинающие программиста боятся отладки, если та требует изменения кода. Их можно понять, ведь это немного похоже на вскрытие с исследовательскими целями. Но вы должны научиться вызывать свой код, экспериментировать с ним и понимать, что ничего из того, что вы временно делаете с ним, не сделает его хуже. Если у вас есть такой страх, найдите наставника. Мы теряем множество хороших программистов в самом начале их обучения из-за этого страха. + +Следующее: [Как отлаживать, разделяя пространство проблемы](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/ru/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md b/ru/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md new file mode 100644 index 0000000..90beab8 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -0,0 +1,15 @@ +# Как отлаживать, разделяя пространство проблемы +[//]: # (Version:1.0.0) +Отладка это интересно, потому что она начинается с проблемы. Вы думаете, что программа делает одно, но на самом деле она делает что-то другое. Не всегда это настолько просто, но все примеры, которые я мог бы привести, будут надуманными по сравнению с реальными случаями. Отладка требует творчества и смекалки. Если и есть какой-то один ключ к отладке, то он заключается в приеме "разделяй и властвуй" в отношении проблемы. + +Предположим, к примеру, что вы написали программу, которая должна выполнять десять инструкций подряд. Затем вы запускаете ее, и она вылетает. Поскольку вы не планировали вылет программы, у вас появляется проблема. Когда вы смотрите на вывод программы, вы видите, что первые семь инструкций были выполнены успешно. Оставшиеся три инструкции не видны в выводе, поэтому пространство проблемы сужается: программа вылетает либо на восьмой, либо на девятой, либо на десятой инструкции. + +Сможете ли вы поставить эксперимент, чтобы увидеть, где вылетает программа? Конечно. Вы можете использовать отладчик или добавить вывод в консоль (либо их эквивалент на вашем языке программирования) после восьмой и девятой инструкций. Когда вы запустите программу снова, пространство проблемы станет еще уже, например, вы увидите, что программа вылетает на девятой инструкции. Я считаю, что помнить о точном определении проблемы помогает сосредоточиться на ее решении. Когда несколько человек работают под давлением и стрессом над задачей, очень легко забыть о том, что в ней является главной проблемой. + +Ключ к отладке по принципу "разделяй и властвуй" такой же, как и при разработке алгоритмов. Вы разделяете пространство программы, в котором может быть проблема, пополам. Вам не придется делать это слишком долго, и вы быстро будете продвигаться в отладке. Но что такое то пространство, где находится ошибка и которое следует поделить пополам? Именно здесь на помощь приходят смекалка и опыт. + +Начинающим программистам кажется, что ошибка может быть в каждой строке кода. У них еще нет того понимания программы, которое появится позже с опытом. Они не видят все свойства и факторы программы, такие как пространство исполняемого кода, структура данных, управление памятью, взаимодействие с внешним кодом, рискованный код, простой код. Для опытного программиста эти факторы составляют неполную, но крайне полезную модель всего того, что может пойти не так. Наличие такой модели в голове очень эффективно помогает обнаружить точное место проблемы. + +Когда вы разделили все пространство программы на все места, где может быть ошибка, вам предстоит определить, где именно она находится. В простом случае, когда вопрос стоит как "В какой неизвестной мне строке падает программа?", вы можете спросить себя: "Неизвестная мне строка с ошибкой находится до или после этой строки, которая по моему мнению должна исполняться в середине программы?" Как правило, вы будете не настолько удачливы, чтобы обнаружить, что ошибка кроется в одной строке или даже в одном блоке кода. Чаще проблема будет звучать как "Либо в этом графе есть указатель на некорректный объект, либо мой алгоритм некорректно складывает переменные в этом графе". В этом случае, возможно, вам придется написать небольшую программу для проверки указателей, чтобы решить, какую из частей этого пространства проблемы можно исключить. + +Следующее: [Как устранять баги](03-How-to-Remove-an-Error.md) diff --git a/ru/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md b/ru/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md new file mode 100644 index 0000000..9153408 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -0,0 +1,9 @@ +# Как устранять баги +[//]: # (Version:1.0.0) +Я намеренно разделил исследование хода исполнения программы от исправления багов. Но, разумеется, отладка означает и устранение ошибки. В идеале вы прекрасно поймете код и поймаете "Ага"-момент, когда вы четко увидите баг и способ исправить его. Но это не всегда будет возможно, поскольку зачастую ваша программа будет использовать недостаточно документированные сторонние системы, насчет работы которых у вас не будет полной ясности. В других случаях сам код будет настолько сложен, что ваше понимание его будет несовершенным. + +При исправлении бага важно внести наименьшие изменения, которые его устранят. Вы можете заметить другие места в коде, которые потребуют улучшений, но не вносите их одновременно с исправлением ошибки. Старайтесь применять научный метод: изменять только одно зараз. Лучший способ для этого: воспроизвести баг, внести исправления, затем перезапустить программу и убедиться, что бага больше нет. Конечно, иногда придется менять не одну, а несколько строк кода, но концептуально все равно старайтесь вносить точечные изменения для исправления ошибки. + +Иногда в программе присутствует несколько багов, очень похожих друг на друга. Определить их и исправить по одному - это ваша задача. Иногда неясно, что должна делать программа или к чему стремился автор исходного кода. В этом случае вы должны применить свой опыт и знания и придать свой собственный смысл коду. Решите, что он должен делать, и добавьте комментарии об этом, либо обозначьте это иным способом. Затем исправьте код согласно своему пониманию. Это навык разработчика среднего или продвинутого уровня, и иногда он гораздо сложнее, чем написание оригинальной функции с нулю, но реальный мир часто бывает беспорядочен. Иногда вам придется исправлять системы, которые вы не можете переписать с нуля. + +Следующее: [Как отлаживать, используя логирование](04-How-to-Debug-Using-a-Log.md) \ No newline at end of file diff --git a/ru/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md b/ru/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md new file mode 100644 index 0000000..6260571 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -0,0 +1,13 @@ +# Как отлаживать, используя логи +[//]: # (Version:1.0.0) +Логирование - это практика написания программ таким образом, что они выдают последовательность информативных записей, называемых логом. Вывод в консоль - это создание небольшого, обычно временного лога. Начинающие программисты должны понимать и использовать логи, поскольку их знания в программировании ограничены. Системные архитекторы должны понимать и использовать логи, потому что они работают со сложными системами. Количество информации, которую выдает лог, должно быть настраиваемым, желательно во время выполнения программы. В общем случае, логирование имеет три основных преимущества: + +- Логи могут дать полезную информацию о багах, которые трудно воспроизвести (например, такие, которые воспроизводятся на боевом окружении, но не на тестовом) +- Логи могут давать статистику и данные о производительности, такие как время между выполнением команд +- Если логи можно настраивать, то они помогают собрать общую информацию для устранения непредвиденных специфических проблем без необходимости модифицировать или перезапускать код + +Количество выводимой в лог информации это всегда компромисс между информативностью и краткостью. Избыток информации сделает лог тяжелым и вызовет *слепоту прокрутки*, усложняя поиск нужного. Недостаток информации может просто сделать лог бесполезным. По этой причине полезно делать логи настраиваемыми. Как правило, каждая запись в логе отображает свое место в исходном коде, исполняющий ее поток, если он есть, точное время исполнения и, обычно, дополнительную информацию вроде значений переменных, объем свободной памяти, число объектов с данными и так далее. Эти записи покрывают весь исходный код, особенно основные функциональные узлы и рискованный код. Записи можно распределять по уровням, и настраивать в конфигурации вывод только записей определенного уровня. Лог следует проектировать таким образом, чтобы его записи помогали решать проблемы программы, которые вы предвидите. Предусматривайте и проблему измерения производительности. + +Если у вас есть постоянный лог, вывод в консоль можно выполнить в рамках записей лога, и некоторые из отладочных сообщений стоит перманентно включить в систему логирования. + +Следующее: [Как определять проблемы производительности](05-How-to-Understand-Performance-Problems.md) diff --git a/ru/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md b/ru/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md new file mode 100644 index 0000000..78576f8 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -0,0 +1,11 @@ +# Как определять проблемы производительности +[//]: # (Version:1.0.0) +Изучение проблем производительности так же неизбежно, как и освоение отладки. Даже если вы в точности и совершенстве понимаете затраты на исполнение вашего кода, он будет взаимодействовать с другим программным обеспечением, над которым у вас нет будет такого контроля или понимания. Как бы то ни было, на практике проблемы производительности немного отличаются и проще, чем отладка в целом. + +Предположим, что вы или ваши клиенты считают систему или одну из подсистем слишком медленной. Перед тем, как вы попытаетесь ускорить ее, вам стоит построить ее мысленную модель и определить, почему она медленная. Вы можете использовать профилировщик или хороший лог, чтобы определить, где именно затрачивается время или иной ресурс системы. Существует известное утверждение, что 90% времени затрачивается на 10% кода. Я бы добавил к этому важность затрат на чтение и запись в оценке проблем производительности. Часто большая часть времени тратится либо на чтение информации, либо на ее запись. Хорошим первым шагом в построении мысленной модели проблемы будет нахождение затратных операций чтения и записи и 10% кода, занимающих большую часть ресурса. + +Существует множество измерений в производительности компьютерной системы и множество потребляемых ресурсов. Первое, что стоит измерить, это реальное время на исполнение программы. Логирование этого времени особенно полезно тем, что оно может указать на непредвиденные обстоятельства, которые возникают в ситуациях, когда использовать профилировщик непрактично. Однако, этот параметр не всегда дает полную картину происходящего. Иногда вычисления, которые требуют чуть больше общего времени, но занимают меньше процессорного времени, покажут себя лучше в реальном окружении. Аналогично, память, пропускная способность сети, доступ к базе данных или другому серверу могут оказаться, в конечном счете, гораздо дороже, чем процессорное время. + +Загруженность общих ресурсов, которые синхронизированы между собой, может привести к взаимной блокировке и ресурсному голоду. Взаимная блокировка - это невозможность продолжить исполнение программы из-за недостаточной синхронизации запрашиваемых ресурсов. Ресурсный голод - это невозможность правильно запланировать работу компонента. Если это можно предусмотреть, то лучше всего с самого старта проекта иметь способ измерения загруженности ресурсов. Даже если загруженности не будет, очень полезно иметь возможность утверждать это с уверенностью. + +Следующее: [Как устранять проблемы производительности](06-How-to-Fix-Performance-Problems.md) diff --git a/ru/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md b/ru/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md new file mode 100644 index 0000000..384480c --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -0,0 +1,13 @@ +# Как устранять проблемы производительности +[//]: # (Version:1.0.0) +Большинство проектов можно с относительно небольшими усилиями ускорить в 10-100 раз относительно их первой версии. В условиях сжатых сроков выхода на рынок разумно и эффективно выбирать ту реализацию, которая проще и быстрее остальных. Однако, производительность это часть удобства использования, поэтому часто ее стоит оценивать более внимательно. + +Главное в улучшении производительности сложной системы - это проанализировать ее достаточно тщательно, чтобы найти "узкие места", то есть те места, где запрашивается наибольший объем ресурсов. Нет большого смысла оптимизировать функцию, которая занимает только 1% процессорного времени. Если вы не уверены, что изменение ускорит систему или ее значительную часть хотя бы в два раза, то стоит хорошо подумать, стоит ли это вообще делать. Как правило, такие способы ускорения есть. Оценивайте также затраты на тестирование и проверки, которые потребует ваше изменение кода. Каждое изменение кода влечет за собой необходимость тестирования, поэтому лучше иметь небольшое число значительных изменений. + +После того, как вы добились двукратного улучшения производительности в одном месте, стоит снова проанализировать программу и определить следующее по затратам узкое место. Тогда можно заняться им. + +Часто узкие места в производительности будут представлять собой что-то вроде подсчета коров по ногам и последующего деления на четыре вместо обычного подсчета по головам. Например, я часто забывал дать собственный индекс часто запрашиваемому столбцу в реляционной базе управления данных, что замедляло весь процесс минимум в 20 раз. Среди других примеров: ненужные операции чтения и записи в циклах, отладочные сообщения, ставшие неактуальными, избыточное выделение памяти и в особенности неумелое использование библиотек и сторонних фреймворков, которые плохо документированы в части производительности. Такой вид улучшений легко определить и с ходу внести в программу. + +Что делать, когда очевидных мест для улучшений не осталось? Вы можете продолжать искать узкие места на более глубоком уровне или пересмотреть весь дизайн системы. Последнее дает прекрасную возможность продемонстрировать свои умения программиста не только в реализации нового дизайна системы, но и в умении убедить своего босса в том, что это необходимо. Тем не менее перед тем, как вы начнете убеждать его в необходимости коренных изменений, спросите себя, ускорит ли ваше решение систему в 5-10 раз. + +Следующее: [Как оптимизировать циклы](07-How-to-Optimize-Loops.md) diff --git a/ru/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md b/ru/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md new file mode 100644 index 0000000..63e387f --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -0,0 +1,15 @@ +# Как оптимизировать циклы +[//]: # (Version:1.0.0) +Иногда вам будут встречаться затратные по времени циклы или рекурсивные функции, которые окажутся узкими местами в вашей программе. Перед тем, как вы попытаетесь ускорить цикл, потратьте некоторое время на то, чтобы понять, можно ли избавиться от него полностью. Сработает ли здесь какой-нибудь другой алгоритм? Можно ли вычислить это параллельно с другим вычислением? Если вам не удалось найти обходной путь, тогда оптимизируйте цикл. Это просто: вынесите из него все, что можно. В конце концов, эта операция требует не только смекалки, но и понимания, сколько затрачивается на каждое выражение и операцию. Вот несколько предложений: + +- Уберите операции с плавающей точкой +- Не выделяйте впустую новые блоки памяти +- Держите константы в одном месте +- Вынесите операции чтения и записи в буфер +- Старайтесь не использовать деление +- Старайтесь не использовать затратные приведения типов данных +- Перемещайте указатель вместо того, чтобы пересчитывать индексы + +Стоимость каждой из этих операций зависит от вашей конкретной системы. Где-то компиляторы и аппаратное обеспечение выполнят их вместо вас. Разумеется, чистый и эффективный код лучше, чем тот, который требует понимания специфичной платформы. + +Следующее: [Как справиться с расходами на операции чтения и записи](08-How-to-Deal-with-IO-Expense.md) diff --git a/ru/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md b/ru/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md new file mode 100644 index 0000000..52500ff --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -0,0 +1,13 @@ +# Как справиться с расходами на операции чтения и записи +[//]: # (Version:1.0.0) +В большинстве случаев процессоры сами по себе работают быстро по сравнению со взаимодействием с аппаратными устройствами. Затраты на это взаимодействие обычно объединяются под словами операции чтения и записи и включают сетевые запросы, чтение и запись на диски, запросы в базы данных, чтение и запись файлов и другое использование аппаратной части, иногда расположенной не совсем рядом с процессором. Таким образом, построение быстрой системы это чаще улучшение операций чтения и записи, чем улучшение кода в цикле или даже совершенствование алгоритма. + +Существует две фундаментальные техники по улучшению операций чтения и записи: кэширование и форматирование данных. Кэширование позволяет избежать чтения-записи (обычно чтения некого абстрактного значения) с помощью сохранения копии значений локально. Таким образом, операция чтения для получения значения не повторяется. Главное в кэшировании четко обозначить, какие данные являются исходными, а какие - копиями. Должен существовать только один исходник. Кэширование опасно тем, что иногда копия может не отразить изменения, произошедшие в исходных данных. + +Форматирование данных - это удешевление операций чтения и записи за счет более эффективного представления данных. Зачастую это конфликтует с другими требованиями к данным, вроде удобочитаемости и переносимости. + +Часто формат данных можно улучшить в 2-3 раза относительно их первоначального представления. Техники, которые позволяет сделать это, включают представление в двоичном виде вместо представления в удобочитаемом виде, передача справочников символов вместе с данными, так что длинные символы не нуждаются в кодировании, и, в крайнем случае, способы вроде алгоритма Хаффмана. + +Третий способ, который иногда возможен, это перенос вычислений ближе к самим данным. Например, если вы читаете данные из базы и выполняете с ними простые операции вроде сложения, то стоит попытаться перенести эту операцию на сервер базы данных. Этот способ очень сильно зависит от типа вашей системы, но вам стоит отдельно изучить его возможность. + +Следующее: [Как управлять памятью](09-How-to-Manage-Memory.md) \ No newline at end of file diff --git a/ru/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md b/ru/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md new file mode 100644 index 0000000..9ed8376 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -0,0 +1,15 @@ +# Как управлять памятью +[//]: # (Version:1.0.0) +Память - это ценнейший ресурс, который вы не можете себе позволить исчерпать. Какое-то время вы можете игнорировать ее, но в один момент вам придется решать, как ею управлять. + +Пространство памяти, которое должно сохраняться за пределами одной подпрограммы, часто называется *выделенной кучей*. Участок памяти без указателей на него бесполезен и называется *мусором*. В зависимости от системы, которую вы используете, вы можете решить удалить в явном виде память, выделенную под данные, которые вот-вот станут мусором. Но чаще всего у вас будет возможность использовать *сборщик мусора*. Он определяет мусорную память и освобождает ее автоматически, без вмешательства программиста. Сборщик мусора это прекрасное средство, оно уменьшает число ошибок в коде, позволяет писать его короче и понятнее с наименьшими затратами. Используйте его, когда это возможно. + +Но даже со сборщиком мусора вы можете забить всю память мусорными данными. Классическая ошибка - использовать хеш-таблицу в качестве кэша и забыть удалить ссылки в ней. Поскольку ссылка остается, данные по ней недосягаемы, и ссылка бесполезна. Это называется *утечкой памяти*. С самого начала разработки следует следить за утечками памяти и устранять их. Если у вас есть долгоработающие системы, то память может никогда не заканчиваться при тестировании, но будет исчерпана пользователями при реальной работе. + +Создание новых объектов это относительно затратная операция в любых системах. Память, выделенная напрямую под локальные переменные подпрограммы, однако, обычно дешевле из-за простой политики ее высвобождения. Избегайте создания ненужных объектов. + +Важный момент происходит, когда вы можете определить верхнюю границу числа требуемых объектов. Если все объекты занимают одинаковый объем памяти, то вы можете выделить под них один блок памяти или буфер. Все необходимые вам объекты можно создавать и удалять внутри этого блока по принципу ротации, так что иногда это называют кольцевым или циклическим буфером. Обычно он быстрее, чем выделенная куча. + +Иногда вам придется явно освобождать выделенное пространство памяти вместо того, чтобы полагаться на сборщик мусора. В этом случае вы должны тщательно проанализировать каждую часть выделенной памяти и разработать способ ее высвобождения в нужный момент времени. Способ может отличаться для каждого типа объектов, который вы создаете. Вы должны убедиться, что каждой операции выделения памяти соответствует операция ее освобождения. Это непросто, поэтому для упрощения задачи программисты как правило реализуют сборщик мусора в простой форме, например, в виде подсчета ссылок на объекты. + +Следующее: [Как устранять плавающие баги](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/ru/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md b/ru/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md new file mode 100644 index 0000000..81bf3a3 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -0,0 +1,17 @@ +# Как устранять плавающие баги +[//]: # (Version:1.0.0) +Плавающий баг это родственник пятидесятиметрового невидимого скорпиона из глубокого космоса. Этот кошмар воспроизводится так редко, что его трудно наблюдать, но достаточно часто его нельзя просто игнорировать. Вы не можете отладить баг, потому что вы не можете его найти. + +Хотя после восьми часов отладки вы начнете сомневаться в этом, плавающие баги подчиняются тем же самым законам логики, что и все остальное. Что делает их трудными, это неизвестные обстоятельства, в которых они воспроизводятся. Постарайтесь записать все условия, при которых происходит плавающий баг, чтобы вы могли предположить, в чем на самом деле заключается изменчивость бага. Баг может быть связан со значениями данных, например, воспроизводиться, только когда переменной присваивается значение "Вайоминг". Если причина изменчивости не в этом, то следующим пунктом стоит проверить синхронизацию конкуррентности. + +Изо всех сил постарайтесь воспроизвести баг контролируемым способом. Если воспроизвести его не получается, попробуйте поймать его через логирование. Если нужно, напишите специальные логи для этого бага, которые будут записывать то, что вам кажется связанным с ним. Смиритесь с тем, что это будет долгий процесс, если ошибка воспроизводится на боевом окружении и не по вашей прихоти. Подсказки, которые вы можете извлечь из логов, могут не дать вам полного ответа, но должны предоставить достаточно информации для улучшения самих логов. Улучшение системы логирования для боевого окружения может занять много времени. Затем вам придется ждать, пока баг не появится вновь, чтобы получить информацию из обновленных логов. Этот цикл может повториться еще несколько раз. + +Самый глупый плавающий баг, который создал я, заключался в многопоточной реализации одного функционального языка программирования для учебного проекта. Я тщательно обеспечил корректную оценку параллельности программы, правильное использование ядер процессора (всех восьми в данном случае). Я просто-напросто забыл синхронизировать сборщик мусора. Программа могла работать безошибочно долгое время, завершая все задания, которые я ей назначал. Со стыдом признаюсь, я начал подозревать аппаратное обеспечение, прежде чем меня осенило, в чем проблема. + +Недавно на работе у нас был плавающий баг, на который мы потратили несколько недель. У нас есть многопоточное серверное приложение на Java, размещенное на Apache-серверах. Чтобы поддержать быструю смену веб-страниц, мы выполняли все операции чтения и записи в небольшом наборе из четырех потоков, отделенных от потоков, ответственных за смену страниц. Время от времени некоторые из этих четырех потоков "замораживались" и, насколько мы могли понять из логов, прекращали делать что-либо полезное на несколько часов. Поскольку у нас было выделено четыре потока, само по себе это не было большой проблемой. До тех пор, пока не замораживались все четыре потока одновременно. Тогда очереди запросов, освобожденные замороженными потоками, забивали всю свободную память и крашили наш сервер. Нам потребовалась неделя, чтобы просто выявить баг, и за это время мы не смогли понять, в чем причина, вызывающая этот баг, и даже что именно происходило в потоках в тот момент, когда они "застревали". + +Этот пример демонстрирует риск, связанный с использованием стороннего программного обеспечения. Мы использовали лицензионный код, который убирал теги HTML из текста. Хотя, к счастью, у нас был исходный код, мы не изучали его досконально, пока мы не включили логирование на нашем сервере и не увидели, что потоки почтовых сообщений забивались из-за этого лицензионного кода. + +Программа работала прекрасно, за исключением некоторых длинных и необычных текстов. В этом случае время обработки текста становилось пропорциональным квадрату его длины. Если бы такие тексты встречались бы регулярно, мы бы сразу нашли баг. Если бы они вообще не попадались бы, бага просто не было бы. Как это бывает, мы потратили несколько недель, чтобы наконец понять и решить проблему. + +Следующее: [Как научиться проектировать программы](11-How-to-Learn-Design-Skills.md) diff --git a/ru/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md b/ru/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md new file mode 100644 index 0000000..997dede --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -0,0 +1,9 @@ +# Как научиться проектировать программы +[//]: # (Version:1.0.0) +Чтобы научиться проектировать программное обеспечение, наблюдайте за тем, как это делают более опытные коллеги. Затем изучайте хорошо написанные программы. Далее вы можете прочесть несколько книг о новейших техниках проектирования. + +Затем вы должны начать проектировать самостоятельно. Начните с небольшого проекта. Когда вы завершите его, оцените, насколько удачна или неудачна финальная архитектура, и как сильно вы отклонились от первоначальной концепции. Потом переходите на проекты побольше, желательно в сотрудничестве с другими людьми. Навык проектирования требует годы на выработку. Толковый программист может освоить основы за пару месяцев и дальше развиваться самостоятельно. + +Естественно и полезно развивать свой собственный стиль, но помните, что проектирование это искусство, а не наука. Люди, которые пишут об этом книги, заинтересованы в том, чтобы проектирование казалось научным. Не становитесь догматиком в отношении стилей проектирования. + +Следующее: [Как экспериментировать](12-How-to-Conduct-Experiments.md) diff --git a/ru/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md b/ru/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md new file mode 100644 index 0000000..d383923 --- /dev/null +++ b/ru/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -0,0 +1,23 @@ +# Как экспериментировать +[//]: # (Version:1.0.0) +Великий Эдсгер Дейкстра красноречиво объяснил, что информатика не является экспериментальной наукой[ExpCS] и не зависит от электронных устройств. Как он выразился в 1960-е годы [Knife]: + +> ...произошло худшее: предмет стал известен как “computer science”, что, собственно говоря, то же самое, что называть хирургию “knife science”. И в сознании людей прочно укоренилось, что “computer science” - это наука о машинах и периферийном оборудовании. + +Программирование может и не быть экспериментальной наукой, но у большинства программистов нет возможности заниматься тем, что Дейкстра определил как “computer science”. Мы должны работать в области эксперимента подобно некоторым (но не всем) физикам. Если спустя 30 лет можно будет заниматься программированием без экспериментирования, то это будет великим достижением информатики. + +Эксперименты, которые вам придется заниматься, включают: + +- Тестирование систем на небольших примерах данных, чтобы убедиться в их соответствии документации, либо, чтобы понять их ответы, если документации нет +- Тестирование небольших изменений в коде, чтобы удостовериться, что они устраняют баг в программе +- Измерение производительности системы в двух различных окружениях из-за несовершенства знаний о их характеристиках производительности +- Проверка целостности данных +- Сбор статистики, которая может помочь в разрешении сложных и трудновоспроизводимых багов + +Я не думаю, что в этом эссе я смогу объяснить, как проектировать эксперименты. Вам придется научиться этому самостоятельно и практиковаться. Я могу предложить два небольших совета. + +Первое: старайтесь четко обозначать свои исходные предположения или утверждения, которые вы собираетесь проверить. Очень полезно записывать их, особенно, если вы работаете в коллективе. + +Часто вам придется проектировать серию экспериментов, каждый из которых опирается на знания, полученные в результате предыдущего. Таким образом, следует проектировать эксперименты так, чтобы получать как можно больше информации. К сожалению, это противоречит принципу простоты экспериментов. Вам придется развивать свою экспертизу в этой области самостоятельно. + +Следующее: [Командные навыки. Почему важно оценивать задачи](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/ru/1-Beginner/README.md b/ru/1-Beginner/README.md new file mode 100644 index 0000000..425a92d --- /dev/null +++ b/ru/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. Начинающий программист +[//]: # (Version:1.0.0) +- Личные навыки + - [Научитесь отлаживать](Personal-Skills/01-Learn-To-Debug.md) + - [Как отлаживать, разделяя пространство проблемы](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [Как устранять баги](Personal-Skills/03-How-to-Remove-an-Error.md) + - [Как отлаживать, используя логи](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [Как определять проблемы производительности](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [Как устранять проблемы производительности](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [Как оптимизировать циклы](Personal-Skills/07-How-to-Optimize-Loops.md) + - [Как справиться с расходами на операции чтения и записи](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [Как управлять памятью](Personal-Skills/09-How-to-Manage-Memory.md) + - [Как устранять плавающие баги](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [Как научиться проектировать программы](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [Как экспериментировать](Personal-Skills/12-How-to-Conduct-Experiments.md) +- Командные навыки + - [Почему важно оценивать задачи](Team-Skills/01-Why-Estimation-is-Important.md) + - [Как оценивать время на разработку](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [Как искать информацию](Team-Skills/03-How-to-Find-Out-Information.md) + - [Как спрашивать людей](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [Как документировать правильно](Team-Skills/05-How-to-Document-Wisely.md) + - [Как работать с плохим кодом](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [Как использовать системы контроля версий](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [Как писать юнит-тесты](Team-Skills/08-How-to-Unit-Test.md) + - [Делайте перерывы, когда вы в тупике](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [Как понять, когда идти домой](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [Как вести себя с трудными людьми](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/ru/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md b/ru/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md new file mode 100644 index 0000000..ddacc04 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -0,0 +1,15 @@ +# Почему важно оценивать задачи +[//]: # (Version:1.0.0) +Чтобы как можно быстрее выпустить программное обеспечение, нужно планировать не только ее разработку, но и документирование, запуск и продвижение. В коммерческих проектах также важны продажи и финансовая составляющая. Без предсказуемости времени разработки невозможно все это запланировать эффективно. + +Хорошая оценка времени на разработку дает предсказуемость. Менеджеры очень любят это. Тот факт, что теоретически и практически невозможно точно предсказать, сколько времени уйдет на разработку, часто упускается менеджерами. Нас все время просят сделать эту невыполнимую вещь, и мы должны себе честно в этом признаться. Однако, будет нечестно не признать невыполнимость этого задания и, когда необходимо, не объяснить это. Вокруг временных оценок много недопониманий, так как люди склонны принимать слова + +> Я думаю, что если я правильно понимаю проблему, то около 50% вероятности, что мы сделаем это за пять недель. При условии, что никто не будет нам мешать все это время. + +в действительности означает + +> Я обещаю все сделать за пять недель, начиная с текущего момента. + +Это общая проблема непонимания требует, чтобы вы в явном виде обсуждали, что именно значит ваша временная оценка со своим боссом или клиентом. Так, словно они дети. Измените свои формулировки оценки, даже если они вам кажутся очевидными. + +Следующее: [Как оценивать время на разработку](02-How-to-Estimate-Programming-Time.md) diff --git a/ru/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md b/ru/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md new file mode 100644 index 0000000..f34e0c9 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -0,0 +1,21 @@ +# Как оценивать время на разработку +[//]: # (Version:1.0.0) +Оценка времени требует практики и труда. Иногда так много труда, что имеет смысл отдельно оценивать время на оценку задачи, особенно, если речь идет об оценке большой задачи. + +Когда вас просят оценить большую задачу, самое честное - потянуть время. Большинство инженеров полны энтузиазма и склонны угождать, а задержка ответа не обрадует спрашивающего. Но выданная с ходу оценка вряд ли будет точной и честной. + +Пока вы думаете над ответом, возможно, получится сделать прототип задачи. Если обстоятельства позволяют, то это самый точный способ оценки, и он позволяет добиться реального прогресса. + +Когда взять время на некоторое исследование задачи невозможно, то сначала вы должны четко и ясно установить, что именно означает ваша оценка. Сформулируйте это значение как первое и заключительное части вашей оценки в письменном виде. Подготовьте письменный ответ, разбирая задачу на более мелкие задания, в идеальном случае, требующие не больше одного рабочего дня. Самое важное здесь - ничего не забыть. Например, очень важно время на документирование, тестирование, планирование, взаимодействие с другими командами, отпуска. Если вы каждый день тратите часть времени на общение с неумными людьми, добавьте отдельную строку на это в общую оценку времени. Это даст вашему боссу общее видение того, что отнимает у вас немного времени, а на что вам его требуется гораздо больше. + +Я знаком с программистами, которые включают такие временные затраты в общую оценку в неявном виде, то есть просто прибавляют их к общему времени работы. Я не советую так делать. Одним из эффектов такого подхода может стать потеря доверия. Например, программист может заложить три дня на задачу, которую он на самом деле собирается выполнить за день. Программист планирует потратить еще два дня на документирование своей работы или на другой полезный проект. Но тот факт, что работа была выполнена только за один день, очень просто выяснить. И тогда может возникнуть впечатление, что программист бездельничал или переоценил задачу. Намного лучше дать четкое описание того, что вы реально собираетесь делать в рамках задачи. Если документирование занимает в два раза больше времени, чем написание кода, и в оценке сказано об этом, то это дает свои преимущества, если это донести до вашего менеджера. + +Включайте все временные затраты в оценку в явном виде. Если задача скорее всего займет один день, но может растянуться на десять дней, если ваш первоначальный подход не сработает, отметьте это в вашей оценке. Либо укажите среднее время задачи согласно вашим оценкам вероятностей разных исходов. Любые риски, связанные с временем на задачу, должны быть включены в оценку. Вряд ли конкретный человек заболеет в конкретный момент времени. Но в большом проекте с множеством программистов обязательно будут те, кто возьмет больничный. То же самое касается отпусков. А какова вероятность обязательного обучающего семинара в рамках всей компании? Если ее можно оценить, включите ее в общую оценку. Кроме этого, еще есть неизвестные факторы. Их по определению не получится оценить по отдельности. Вы можете заложить для них отдельную строку в общей оценке, либо учесть их как-то по-другому. Чего нельзя делать, так это позволять своему боссу забыть об их существовании. Очень легко превратить оценку времени в расписание, если не учитывать неизвестные факторы. + +В рамках команды следует стараться, чтобы оценку выполняли те люди, которые будут выполнять задачу, и чтобы оценка была согласована внутри всей команды. Люди отличаются по навыкам, опыту, готовности и уверенности. Неприятности начинаются, когда сильный программист оценивает задачу для себя, а более слабые программисты затем вынуждены придерживаться этой оценки. Когда вся команда согласна с построчным разбиением оценок затрат на задачи, это облегчает общее понимание задач и дает возможность тактически перераспределить нагрузку с более слабых членов команды на более сильных. + +Если в задаче присутствуют большие риски, которые невозможно оценить, ваша обязанность донести это до менеджера так, чтобы тот не брал на себя обязательства, связанные с ними. В этом случае стоит сделать все возможное, чтобы снизить эти риски. + +Если вы сможете убедить свою компанию использовать *экстремальное программирование*, то вам придется оценивать только относительно небольшие задачи. Это гораздо интереснее и продуктивнее. + +Следующее: [Как искать информацию](03-How-to-Find-Out-Information.md) diff --git a/ru/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md b/ru/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md new file mode 100644 index 0000000..5139677 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -0,0 +1,19 @@ +# Как искать информацию +[//]: # (Version:1.0.0) +То, что вы ищете, определяет, какими способами вам следует это искать. + +Если вы ищете информацию о *конкретных знаниях*, которые объективны и легко проверить, например, последняя версия патча для программного обеспечения, то лучше вежливо спросить об этом в интернете или в дискуссионной группе. Не ищите в интернете то, что связано с мнением или субъективной интерпретацией, количество бреда здесь слишком велико. + +Если вы ищете *общие знания о чем-то субъективном*, историю мнений людей о предмете, то идите в библиотеку (я имею в виду настоящее здание с книгами). Например, идите туда, чтобы узнать что-нибудь о математике, грибах или мистицизме. + +Если вам нужно узнать, *как сделать что-то нетривиальное*, достаньте две-три книги, посвященные этой теме, и прочтите их. В интернете вы можете узнать, как сделать тривиальные вещи, вроде установки пакета программного обеспечения. Вы даже можете узнать серьезные вещи, например, хорошие техники программирования, но здесь легко потратить гораздо больше времени на поиск и отбор результатов и попытки определить, насколько авторитетен источник, чем на чтение соответствующей части в серьезной книге. + +Если вы ищете *информацию, которую скорее всего никто не знает*, например, "работает ли это новое программное обеспечение с огромными наборами данных?", все равно стоит поискать ответ в интернете и в библиотеке. Когда эти способы будут исчерпаны, вы можете спроектировать эксперимент, чтобы убедиться в истинности найденных ответов. + +Если вас интересует мнение или экспертное суждение с учетом некоторых уникальных обстоятельств, поговорите с экспертом. Например, если вы хотите знать, хорошая ли это идея написать современную систему управления данных на Lisp, вам стоит поговорить с экспертом Lisp и с экспертом по базам данных. + +Если вы хотите знать, *какова вероятность*, что существует более быстрый алгоритм для конкретного приложения, поговорите с тем, кто работает в этой области. + +Если вы хотите принять личное решение, которое можете принять только вы, вроде начинать вам свой бизнес или нет, попробуйте составить список аргументов за и против этого решения. Если это не поможет, попробуйте принять решение наугад. Предположим, вы изучили идею со всех сторон, провели нужные исследования, выяснили все обстоятельства, преимущества и недостатки идеи, но все равно не можете решить. Тогда вы должны последовать своему сердцу и сказать своему разуму заткнуться. Множество доступных техник гадания очень полезны для определения ваших подсознательных желаний, так как каждая из них представляет собой совершенно неоднозначный и случайный образ, которому ваше подсознание придаст свое значение. + +Следующее: [Как использовать людей в качестве источников информации](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/ru/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md b/ru/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md new file mode 100644 index 0000000..725ed7e --- /dev/null +++ b/ru/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -0,0 +1,15 @@ +# Как спрашивать людей +[//]: # (Version:1.0.0) +Уважайте время каждого человека и соизмеряйте его со своим. Вопрос дает гораздо больше, чем просто ответ. Человек, которого вы спрашиваете, узнает вас как просто из вашего присутствия, так и по вашему вопросу. Вы узнаете о человеке то же самое, и вдобавок, возможно, вы получаете ответ на ваш вопрос. Как правило, это гораздо важнее, чем ваш вопрос. + +Однако, ценность вопросов уменьшается тем больше, чем чаще вы их задаете. В конце концов, вы отнимаете у человека самое важное: время. Выгоды от общения стоит соизмерять с затратами на него. Более того, конкретные выгоды и затраты отличаются от человека к человеку. Я убежден, что руководитель 100 человек должен тратить 5 минут в месяц на разговор с каждым человеком в организации. Это займет 5% всего времени руководителя. Но 10 минут может быть слишком много для такого числа, а 5 минут может быть много, если в компании 1000 сотрудников. Число времени, которое вы тратите на беседы с каждым человеком в вашей компании, зависит от роли человека (больше, чем от должности). Вам следует разговаривать с вашим боссом чаще, чем с боссом вашего босса, но и с ним вам стоит немного разговаривать. Это может оказаться некомфортным, но я считаю, что ваша обязанность каждый месяц немного разговаривать со всеми вашими руководителями, несмотря ни на что. + +Главное правило: все получают пользу от небольшой беседы с вами. И чем чаще происходит беседа, тем меньше пользы они получают. Ваша работа состоит в том, чтобы дать этим людям пользу от разговора с вами и получить ее самому, сохраняя баланс между нею и потраченным временем. + +Важно уважать свое собственное время. Если разговор с кем-то, несмотря на то, что он займет время этого человека, поможет сохранить вам ваше время, то вам стоит провести этот разговор. Если только вы не считаете, что потраченное на разговор время этого человека более важно для всей организации. + +Странным примером всего этого является летний стажер. От стажера на высокотехнической должности нельзя ожидать больших свершений, но можно ожидать, что он будет донимать вопросами всех подряд. Почему это позволяется? Потому что те, кого донимает стажер, получают от него важную возможность покрасоваться. У них, возможно, появляется шанс услышать новые идеи, посмотреть с другой точки зрения на проект. Может быть, они попытаются нанять стажера, но даже если это не так, все равно от него много пользы. + +Каждый раз, когда вы считаете, что людям есть что сказать, вам следует спрашивать их мнение. Это льстит им и позволяет вам узнать что-то новое, научить их чему-то новому. Хорошему программисту редко нужны советы от вице-президента по продажам, но когда они нужны, спросите их. Я однажды попросил разрешить мне послушать несколько звонков от ребят из отдела продаж, чтобы лучше понять их работу. Это заняло не больше 30 минут, но думаю, что это произвело на них большое впечатление. + +Следующее: [Как документировать правильно](05-How-to-Document-Wisely.md) \ No newline at end of file diff --git a/ru/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md b/ru/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md new file mode 100644 index 0000000..72088f0 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -0,0 +1,20 @@ +# Как документировать правильно +[//]: # (Version:1.0.0) +Жизнь слишком коротка, чтобы писать ерунду, которую никто не будет читать. Если вы пишете плохо, никто не будет это читать. Так что лучше всего документировать хорошо и немного. Менеджеры часто не понимают этого, потому что даже плохая документация дает им ложное чувство уверенности, что они не зависят от своих программистов. Если кто-то абсолютно настаивает, чтобы вы писали никому ненужную документацию, скажите "да" и начинайте спокойно искать новую работу. + +Чтобы снизить запрос на документирование, нет ничего более эффективного, чем дать точную оценку времени, которое на него потребуется. Реалии жизни холодны и суровы: документирование, как и тестирование, может занять гораздо больше времени, чем разработка. + +Написание хорошей документации это, прежде всего, умение хорошо писать. Я предлагаю вам найти книги о том, как хорошо писать, изучить их и практиковаться. Но даже если вы плохой писатель или плохо владеете языком, на котором должны документировать, все, что вам реально нужно, это золотое правило "Поступай с другими так, как вы хотите, чтобы поступали с вами". Подумайте о тех, кто будет читать вашу документацию, что им будет нужно найти в ней, как вы можете это до них донести. Уже с этим вы будете лучше среднего автора документации и хорошим программистом. + +Когда дело касается документирования самого кода в противоположность написанию документации для непрограммистов, лучшие программисты, которых я знаю, придерживаются универсального принципа писать самодокументируемый код и добавлять комментарии только там, где невозможно объяснить решения самим кодом. Для такого подхода есть две веские причины. Во-первых, любой, кому понадобится документация кода, в большинстве случаев сможет и предпочтет читать сам код. Разумеется, сделать это проще опытным программистам, чем начинающим. Но гораздо важнее, что код и документация не могут противоречить друг другу, если отдельной документации нет. Исходный код в худшем случае может быть написан плохо и непонятно. Документация, если она написана плохо, может лгать, а это в тысячу раз хуже. + +Это не облегчает работу ответственным программистам. Как писать самодокументируемый код? Что это вообще значит? Это значит: + +- Писать код, думая о том, что кому-то придется его читать +- Применять золотое правило выше +- Выбирать решение, которое очевидно, даже если менее очевидное решение быстрее +- Жертвовать небольшими оптимизациями вместо того, чтобы делать код менее понятным +- Думать о читателе кода и тратить больше своего драгоценного времени на то, чтобы ему было проще +- Никогда не называть функции `foo`, `bar` или `doIt`! + +Следующее: [Как работать с плохим кодом](06-How-to-Work-with-Poor-Code.md) \ No newline at end of file diff --git a/ru/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md b/ru/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md new file mode 100644 index 0000000..7f72475 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -0,0 +1,11 @@ +# Как работать с плохим кодом +[//]: # (Version:1.0.0) +Иногда приходится работать с чужим плохо написанным кодом. Не стоит плохо думать об авторах этого кода, пока вы не поймете полностью их ситуацию. Возможно, они работали быстро и под давлением, чтобы успеть по графику. Как бы то ни было, чтобы работать с плохим кодом, вам надо его понять. Чтобы понять его, нужно время, и его надо откуда-то взять из вашего текущего графика. На этом следует настаивать. Чтобы понять код, вам придется читать исходники и экспериментировать с ним. + +Это отличный момент начать документировать, даже если пока только для себя. Попытка задокументировать код вынудит вас посмотреть на него с разных точек зрения, которые вы до этого не рассматривали, и конечный документ может получиться очень полезным. Пока вы занимаетесь этим, прикиньте, сколько займет переписать весь код или его некоторую часть. Сохранит ли время переписывание части кода? Сможете ли вы больше доверять коду, если вы перепишите его? Здесь опасайтесь самоуверенности. Если вы перепишете код, то вам будет проще, но будет ли проще следующему человеку, который будет работать с кодом? Если вы перепишите код, то как много придется тестировать? Не перевесит ли необходимость тестирования нового кода все преимущества, которые он принесет? + +В любой оценке времени, которую вы делаете для работы с чужим кодом, качество этого кода должно влиять на ваше восприятие рисков проблем и неизвестных факторов. + +Важно помнить, что абстракция и инкапсуляция, два лучших средства программиста, особенно применимы к плохому коду. Возможно, вы не сможете переделать целиком большой блок кода, но если вы добавите новый уровень абстракции к нему, то сможете добиться некоторых преимуществ без переделки всего кода. В частности, вы можете отделить особенно плохие части кода, чтобы отрефакторить их независимо от остального кода. + +Следующее: [Как использовать системы контроля версий](07-How-to-Use-Source-Code-Control.md) \ No newline at end of file diff --git a/ru/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md b/ru/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md new file mode 100644 index 0000000..dd2752f --- /dev/null +++ b/ru/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -0,0 +1,9 @@ +# Как использовать системы контроля версий +[//]: # (Version:1.0.0) +Системы контроля версий (также известные как системы контроля кода) позволяют вам эффективно управлять проектами. Они очень полезны для программиста-одиночки и жизненно необходимы для группы разработчиков. Они отслеживают все изменения во всех версиях кода, так что ни одна строка кода не может быть потеряна навсегда. Кроме этого, они позволяют присвоить осмысленное название изменениям. С помощью таких систем можно писать отладочный код с уверенностью, ведь весь модифицируемый код можно хранить отдельно от исходного работающего. Новый код потом можно показать всей команде или сразу выпустить. + +Я довольно поздно оценил все преимущества систем контроля версий, но теперь без них я не начну даже небольшой личный проект. Вообще они нужны, когда вы работаете в команде с одной кодовой базой. Но у них есть другое важное преимущество: они поощряют думать о коде как о растущей системе. Поскольку каждое изменение отмечено своим именем или номером, постепенно приходишь к мысли, что программное обеспечение это видимая последовательная серия изменений в коде. Я думаю, что это особенно полезно для начинающих программистов. + +Хорошая техника использования системы контроля версий заключается в том, чтобы постоянно держать свой собственный код в пределах нескольких дней от актуального. Код, который не может быть закончен за несколько дней, проверяется, но таким образом, чтобы он был неактивным и не вызывался в действующей системе, а значит, не создавал проблем для других. Ошибки, замедляющие работу товарищей по команде, непростительны и часто являются табу. + +Следующее: [Как писать юнит-тесты](08-How-to-Unit-Test.md) diff --git a/ru/1-Beginner/Team-Skills/08-How-to-Unit-Test.md b/ru/1-Beginner/Team-Skills/08-How-to-Unit-Test.md new file mode 100644 index 0000000..0b37814 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -0,0 +1,9 @@ +# Как писать юнит-тесты +[//]: # (Version:1.0.0) +Юнит-тестирование, то есть тестирование отдельных частей кода командой, написавшей его, это часть программирования, а не что-то отдельное от него. Проектирование того, как будет тестироваться код, это часть общего проектирования кода. Вам следует записывать планы по тестированию, даже если это всего одна фраза. Иногда тест окажется простым: "Хорошо ли выглядит кнопка?". Иногда он будет сложным: "Этот алгоритм сопоставления возвращает правильные совпадения?" + +Когда возможно, используйте проверки утверждений и тестовые драйверы. Они не только помогут найти баги в начале разработки, но будут полезны позже и позволят устранить более сложные проблемы. + +Экстремальные программисты много пишут об эффективном юнит-тестировании. Я могу только посоветовать ознакомиться с их трудами на эту тему. + +Следующее: [Делайте перерывы, когда вы в тупике](09-Take-Breaks-when-Stumped.md) \ No newline at end of file diff --git a/ru/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md b/ru/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md new file mode 100644 index 0000000..dc7d331 --- /dev/null +++ b/ru/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -0,0 +1,5 @@ +# Делайте перерывы, когда вы в тупике +[//]: # (Version:1.0.0) +Когда вы в тупике, сделайте перерыв. Я иногда медитирую 15 минут, когда захожу в тупик, и проблема неожиданно разрешается, когда я возвращаюсь к ней. Ночной отдых иногда выполняет такую же роль в более широком масштабе. Возможно, поможет временное переключение на другую задачу. + +Следующее: [Как понять, когда идти домой](10-How-to-Recognize-When-to-Go-Home.md) diff --git a/ru/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md b/ru/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md new file mode 100644 index 0000000..2b9be7b --- /dev/null +++ b/ru/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -0,0 +1,16 @@ +# Как понять, когда идти домой +[//]: # (Version:1.0.0) +Программирование - это деятельность, которая также является культурой. К сожалению, это не та культура, которая ценит психическое и физическое здоровье. По культурно-историческим причинам (например, необходимость работать по ночам на ненагруженных компьютерах) и из-за сильного давления выпустить продукт на рынок программисты традиционно перерабатывают. Не думаю, что стоит верить всему, что рассказывают, но мне кажется, что 60 рабочих часов в неделю это распространенный график, а 50 часов это практически минимум. Это значит, что часто требуется гораздо больше. И это серьезная проблема для хорошего программиста, который отвечает не только за себя, но и за своих коллег. Вы должны понимать, когда идти домой, и иногда, когда предложить пойти домой своим коллегам. Здесь не может быть четких правил для решения проблемы, так же, как не может быть однозначных правил о том, как воспитывать детей. Все люди разные. + +Свыше 60 рабочих часов в неделю для меня огромная нагрузка, которую я могу выдержать лишь небольшое время (около недели). Но иногда от меня ожидается именно столько. Не знаю, справедливо ли ожидать от человека 60 часов работы в неделю. Я не уверен, что даже 40 часов это справедливо. Однако, я уверен, что глупо работать так много, чтобы почти не извлекать пользы от дополнительных часов работы. Для меня лично этот предел лежит за 60 часами в неделю. Я лично считаю, что программист должен проявлять благородство и нести эту тяжелую ношу. Однако, быть козлом отпущения - не обязанность программиста. Печальный факт заключается в том, что часто программистов просят быть козлами отпущения, чтобы устроить для кого-то представление, например, когда менеджер пытается впечатлить руководителя. Программисты часто идут на это, потому что они хотят угодить и не умеют говорить "нет". Есть четыре способа защиты от такого отношения: + +- Как можно больше общайтесь со всеми сотрудниками в компании, чтобы никто не мог ввести в заблуждение руководителей относительно того, что происходит +- Научитесь оценивать время на работу и планировать все ее части в явном виде. Дайте всем четкое представление о своем расписании и где его найти +- Научитесь говорить "нет", говорите "нет" всей командой, если это необходимо +- Увольняйтесь, если нет других выходов + +Большинство программистов это хорошие программисты, а хорошие программисты хотят сделать как можно больше. Чтобы достичь этого, они должны эффективно управлять своим временем. Между разогревом перед работой и глубоким погружением в нее всегда должно пройти некоторое время. Многие программисты лучше всего работают, когда они располагают длинными, никем не прерываемыми отрезками времени, в течение которых они могут сосредоточиться и погрузиться в работу. Но люди должны еще и спать, и делать множество других вещей. Каждый должен найти способ сбалансировать свой рабочий ритм и ритм жизни. Каждый программист должен делать все возможное, чтобы обеспечить себя периодами эффективной работы, например, резервируя определенные дни, когда он может отвлекаться только на самые важные собрания. + +Поскольку у меня есть дети, я стараюсь проводить вечера с ними. Лучше всего мне подходит очень долгий рабочий день, затем поспать в офисе или рядом (я работаю очень далеко от дома), затем на следующий день уйти домой достаточно рано, чтобы провести время с моими детьми до того, как они отправятся спать. Этот ритм не очень удобен для меня, но это лучшее, что я смог найти. Отправляйтесь домой, если у вас заразная болезнь. Вы должны идти домой, если у вас суицидальные мысли. Вы должны сделать перерыв или идти домой, если вы думаете об убийстве больше, чем несколько секунд. Вы должны отправить домой человека, если он демонстрирует признаки серьезного умственного расстройства или депрессии. Если из-за усталости у вас возникает соблазн быть более нечестным или вредным, чем вам обычно свойственно, сделайте перерыв. Не используйте кокаин или амфетамины для борьбы с усталостью. Не злоупотребляйте кофеином. + +Следующее: [Как вести себя с трудными людьми](11-How-to-Deal-with-Difficult-People.md) diff --git a/ru/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md b/ru/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md new file mode 100644 index 0000000..34706ea --- /dev/null +++ b/ru/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -0,0 +1,15 @@ +# Как вести себя с трудными людьми +[//]: # (Version:1.0.0) +Скорее всего вам придется иметь дело с трудными людьми. Может быть, вы сами трудный человек. Если вы из тех, у кого часто возникают конфликты с коллегами и руководителями, то вам стоит ценить свою независимость, но одновременно работать над своими навыками взаимодействия с остальными, не принося в жертву свои принципы и ум. + +Это может стать проблемой для некоторых программистов, у которых нет опыта подобных ситуаций, и чей предыдущий жизненный опыт научил моделям поведения, которые не годятся в рабочем окружении. Трудные люди часто привыкают к разногласиям, и на них меньше, чем на остальных, действует социальное давление идти на компромисс. Главное - уважать их должным образом, что больше, чем захотите вы, и меньше, чем могут захотеть подобные люди. + +Программисты вынуждены работать вместе в команде. Когда возникает конфликт, его надо как-то решить, его нельзя игнорировать слишком долго. Трудные люди часто бывают чрезвычайно умны, и им есть, что полезного высказать. Очень важно слушать их и понимать без предубеждения, которое может вызывать их личность. Трудности в общении часто становятся источником разногласий, но их можно преодолеть терпением. Старайтесь держать общение в спокойном и вежливом тоне, не поддавайтесь на уловки увеличить конфликт. После того, как вы потратите разумное время на попытки понять оппонента, примите решение. + +Не позволяйте грубой силе заставлять вас делать то, с чем вы несогласны. Если вы лидер команды, принимайте то решение, которое вы считаете лучшим. Не принимайте решения исходя из личных причин, какими они бы ни были. Будьте готовы объяснить свое решение. Если вы в команде с трудным человеком, не позволяйте, чтобы решение лидера было вызвано любым личным мнением. Если решение не в вашу пользу, примите его. + +Трудные люди меняются и становятся лучше в общении. Я сам был тому свидетелем, но такое случается редко. Как бы то ни было, у всех бывают периоды взлетов и падений. + +Один из самых больших вызовов, встречающихся каждому программисту, особенно лидерам, это держать трудного человека вовлеченным в общую работу. Такие люди больше склонны уклоняться от нее и пассивно сопротивляться. + +Следующее: [Программист среднего уровня](../../2-Intermediate) diff --git a/ru/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md b/ru/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md new file mode 100644 index 0000000..7047cff --- /dev/null +++ b/ru/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -0,0 +1,13 @@ +# Как балансировать качество и время разработки +[//]: # (Version:1.0.0) +Разработка программного обеспечения - это всегда компромисс между тем, что делает само программное обеспечение, и тем, чтобы проект был завершен. Вас могут попросить пожертвовать качеством разработки, чтобы ускорить запуск проекта. Причем жертва может оказаться такой, что это серьезно заденет вашу инженерную или бизнес-ответственность. Например, вас могут попросить применить слабое или неоправданное техническое решение, которое в дальнейшем приведет к множеству проблем. + +В таком случае ваша первая обязанность сообщить о таком требовании своей команде и четко объяснить, чем обернется снижение качества. В конце концов, ваше техническое понимание проекта должно быть гораздо лучше понимания вашего босса. Подчеркните, что теряет проект, что приобретает, и какой ценой потери на текущем этапе придется восполнять на следующем цикле разработки. Здесь очень пригодится общее понимание, которое дает хороший проектный план. Если жертвование качеством влияет на усилия по обеспечению качества, укажите на это боссу и команде по качеству. Если жертвование качеством приведет к увеличению найденных багов после тестирования, укажите и на это. + +Если жертвы неизбежны, вам стоит попытаться отделить некачественный в результате такого решения код в отдельные компоненты, чтобы в дальнейшем вернуться к нему и переписать. Разъясните это своей команде, чтобы они могли запланировать такой подход. + +NinjaProgrammer на Slashdot прислал на эту тему такой шедевр: + +> Помните, что хорошая архитектура устойчива к плохой реализации к коде. Если в коде присутствуют правильные интерфейсы и абстракции, тогда последующий рефакторинг будет менее болезненным. Если вам сложно написать чистый код, который легко поправить, подумайте, в чем проблема архитектуры, из-за которой возникает эта сложность. + +Следующее: [Как управлять зависимостями](02-How-to-Manage-Software-System-Dependence.md) diff --git a/ru/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md b/ru/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md new file mode 100644 index 0000000..0455ab0 --- /dev/null +++ b/ru/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -0,0 +1,13 @@ +# Как управлять зависимостями +[//]: # (Version:1.0.0) +Современное программное обеспечение имеет тенденцию зависеть от множества компонентов, которые могут не быть под вашим непосредственным контролем. Это повышает продуктивность за счет синергии и повторного использования. Однако, каждый такой компонент приносит с собой некоторые проблемы: + +- Как вы будете исправлять баги в компоненте? +- Вынуждает ли компонент вас использовать определенное аппаратное обеспечение или систему? +- Что вы будете делать, если компонент полностью откажет? + +Всегда лучше инкапсулировать компонент таким образом, чтобы он был отделен от основной системы, и его можно было легко заменить. Если компонент покажет свою неработоспособность, вы замените его на другой или напишите свой собственный. Инкапсуляция не улучшает переносимость, но делает переписывание кода проще, что почти также здорово. + +Если у вас есть исходный код компонента, то риски снижаются вчетверо. С исходным кодом вы можете быстрее оценивать компонент, отлаживать, находить новые решения и вносить исправления. Если вы вносите исправления, то о них следует сообщить владельцу компонента, чтобы он включил их в официальный релиз. В противном случае вам придется самостоятельно поддерживать неофициальную версию компонента. + +Следующее: [Как оценивать стороннее программное обеспечение](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/ru/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md b/ru/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md new file mode 100644 index 0000000..2b3684a --- /dev/null +++ b/ru/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -0,0 +1,18 @@ +# Как оценивать стороннее программное обеспечение +[//]: # (Version:1.0.0) +Использование стороннего программного обеспечения это один из самых эффективных способов быстро построить серьезную систему. От него не следует отказываться, но следует изучить связанные с ним риски. Один из самых больших рисков - это период множества багов и почти неработоспособности, случающийся перед тем, как программное обеспечение будет доработано и станет устойчивым продуктом. Прежде чем рассматривать возможность интеграции с программой, разработанной вашей или сторонней компанией, очень важно оценить, насколько она устойчива для использования. Вот десять вопросов, которые вы должны задать себе по этому поводу: + +1. Это выпущенный продукт? (Обещаниям не стоит верить) +2. Существует ли доступный свод знаний об этом программном обеспечении? +3. Вы первый пользователь? +4. Есть ли у разработчиков программы сильный стимул для ее продолжения и развития? +5. Есть ли техническая поддержка? +6. Переживет ли проект уход нынешних разработчиков? +7. Есть ли хотя бы наполовину соответствующая проверенная альтернатива? +8. Известно ли это программное обеспечение вашей команде или компании? +9. Хочет ли ваша команда или компания работать с ним? +10. Сможете ли вы нанять людей для работы с ним, даже если это плохое программное обеспечение? + +Небольшое размышление над этими вопросами демонстрирует огромную ценность хорошо зарекомендовавшего себя свободного программного обеспечения и программного обеспечения с открытым кодом в снижении рисков. + +Следующее: [Как решить: покупать программу или писать свою](04-How-to-Make-a-Buy-vs-Build-Decision.md) diff --git a/ru/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md b/ru/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md new file mode 100644 index 0000000..37b4aa1 --- /dev/null +++ b/ru/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -0,0 +1,16 @@ +# Как решить: покупать программу или писать свою +[//]: # (Version:1.0.0) +Предпринимательская компания или проект, которые пытаются добиться чего-то с помощью программного обеспечения, постоянно вынуждены принимать решения типа *покупать программу или писать свою*. Это выражение неудачно по двум причинам. Оно как будто игнорирует существование свободного и открытого программного обеспечения, которое необязательно покупать. И, что более важно, его стоит переформулировать в *приобрести и интегрировать или написать свое и интегрировать*, потому что затраты на интеграцию обязательны надо учесть. Такие решения требуют редкого сочетания деловой, управленческой и инженерной смекалки. + +- Насколько полно ваши требования совпадают с требованиями, под которые было создано программное обеспечение, рассматривающееся к покупке? +- Какая часть программы, которую вы можете купить, действительно вам нужна? +- Каковы затраты на оценку интеграции? +- Каковы затраты на интеграцию? +- Приобретение этой программы увеличит или уменьшит затраты на долгосрочную поддержку? +- Если вы напишите свое программное обеспечение под свои цели, поставит ли это вашу компанию в нежелательную бизнес-ситуацию? + +Следует как минимум дважды хорошо подумать, прежде чем начинать создавать программу, достаточно большую, чтобы стать основой чьего-то бизнеса. Подобные идеи часто предлагают яркие и оптимистичные люди, которые могут внести большой вклад в вашу команду. Если их идея окажется убедительной, возможно вы захотите изменить свой бизнес-план. Но не инвестируйте необдуманно в решение, которое больше, чем ваш собственный бизнес. + +Рассмотрев эти вопросы, вам стоит подготовить две черновых проектных плана, один с покупкой программного обеспечения, второй с созданием собственного. Это подтолкнет вас оценить затраты на интеграцию. Также стоит рассмотреть затраты на долгосрочную поддержку программы. Чтобы оценить затраты на интеграцию, вам придется тщательно изучить само программное обеспечение перед покупкой. Если это невозможно, то вы берете на себя неразумные риски при покупке и вам стоит отказаться от приобретения программного обеспечения в данном проекте. Если в рассмотрении несколько подобных вопросов о покупке, то придется потратить время на тщательную оценку каждого случая. + +Следующее: [Как расти профессионально](05-How-to-Grow-Professionally.md) diff --git a/ru/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md b/ru/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md new file mode 100644 index 0000000..d911a6d --- /dev/null +++ b/ru/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -0,0 +1,11 @@ +# Как расти профессионально +[//]: # (Version:1.0.0) +Возьмите на себя роль, превышающую вашу ответственность. Выполняйте ту роль, которую вы хотите, чтобы вам поручили. Выражайте признательность и благодарность людям за их вклад в успех организации и за помощь лично вам. + +Если вы хотите стать лидером команды, способствуйте формированию общего согласия в работе. Если вы хотите стать менеджером, возьмите ответственность за график. Обычно вы спокойно можете сделать это, работая с лидером или менеджером, так как это снимет с них большую нагрузку. Если это слишком сложная задача для начала, возьмите на себя обязанности поменьше. + +Оценивайте себя. Если вы хотите стать лучше как программист, спросите программиста, которого вы уважаете, как стать похожим на него. Также вы можете спросить своего босса, который меньше разбирается в этом, но зато имеет большее влияние на вашу карьеру. + +Ищите пути освоить новые навыки, как тривиальные технические вроде освоения новой программной системы, так и трудные социальные, вроде умения писать хорошо. Старайтесь использовать эти навыки в работе. + +Следующее: [Как проводить собеседования](06-How-to-Evaluate-Interviewees.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md b/ru/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md new file mode 100644 index 0000000..40381a3 --- /dev/null +++ b/ru/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -0,0 +1,15 @@ +# Как проводить собеседования +[//]: # (Version:1.0.0) +Оценке потенциальных сотрудников не уделяется должного внимания. Нанятый плохой сотрудник это так же ужасно, как и неудачный брак. Значительная часть усилий каждого должна быть направлена на найм, но это случается редко. + +Есть разные стили собеседования. Некоторые мучительны и направлены оказать на кандидата давление. Это служит ценной цели: выявить под стрессом недостатки характера и слабости. Кандидаты не честнее с интервьюерами, чем с самим собой, а человеческая способность к самообману поразительна. + +Как минимум, вам стоит выделить два часа на устное собеседование по техническим навыкам каждого кандидата. С опытом вы научитесь быстро выяснять, что они знают, и быстро проводить границу с тем, чего они не знают. Кандидаты с уважением относятся к этому. Мне доводилось несколько раз слышать от кандидатов, что качество собеседования было одной из причин выбрать компанию. Хорошие профессионалы хотят, чтобы их нанимали за навыки, а не за последнее место работы, колледж или другие несущественные характеристики. + +При собеседовании также стоит оценивать способность кандидата учиться, она гораздо важнее того, что он уже знает. Также стоит обратить внимание на признаки трудного человека. Их можно распознать, разбирая заметки о собеседовании, но во время интервью может быть трудно их заметить. Умение кандидата общаться и взаимодействовать с людьми гораздо важнее знания новейшего языка программирования. + +Один из читателей рекомендует давать кандидатам тестовое задание на дом. Преимущество этого теста в том, что он позволяет выявить кандидата, который хорошо презентует себя, но не может писать код. Таких людей немало. Я лично не пробовал этот метод, но он кажется разумным. + +Наконец, собеседование - это еще и процесс продажи. Вы продаете свою компанию или проект кандидату. Однако, поскольку вы разговариваете с программистом, не пытайтесь приукрасить правду. Начните с плохого, а затем перейдите к тому хорошему, что есть. + +Следующее: [Как понять, когда применять высокие технологии](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/ru/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md b/ru/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md new file mode 100644 index 0000000..416e5d7 --- /dev/null +++ b/ru/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -0,0 +1,15 @@ +# Как понять, когда применять высокие технологии +[//]: # (Version:1.0.0) +Существует свод знаний об алгоритмах, структурах данных, математике и других вещах, о которых программисты знают, но довольно редко используют в работе. На практике эти замечательные вещи слишком сложны и, как правило, ненужны. Нет смысла улучшать алгоритм, когда большая часть времени тратится на неэффективный запрос к базе данных. Изрядная часть программирования заключается в том, чтобы заставить системы общаться друг с другом и использовать очень простые структуры данных для построения красивого пользовательского интерфейса. + +Когда следует применять высокие технологии? Когда следует открывать серьезные книги, чтобы найти альтернативу обычному алгоритму? Иногда полезно это делать, но такие технологии следует тщательно оценивать. + +Три самых важных соображения о потенциальном использовании какой-либо техники это: + +- Хорошо ли эта техника инкапсулирована? Так что риск для остальных систем невысок, как и общий прирост сложности и затраты на поддержку +- Является ли преимущество использования этой техники значительным (например, в два раза для старой и хорошо разработанной системы или в десять раз для новой)? +- Сможете ли вы протестировать и оценить эту технику эффективно? + +Если хорошо изолированный алгоритм, использующий слегка более сложную логику, может уменьшить нагрузку на аппаратную часть или увеличить производительность в два раза, то будет преступлением не использовать его. Один из способов убедить применить такой подход - это показать, насколько низок риск использования, так как предлагаемая технология хорошо изучена. Остается только риск интеграции. Здесь опыт и экспертиза программиста в сочетании с самой технологией должны сделать интеграцию достаточно простой. + +Следующее: [Как разговаривать с неинженерами](08-How-to-Talk-to-Non-Engineers.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md b/ru/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md new file mode 100644 index 0000000..514934f --- /dev/null +++ b/ru/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -0,0 +1,19 @@ +# Как разговаривать с неинженерами +[//]: # (Version:1.0.0) +В популярной культуре инженеры и в частности программисты часто отделяются от остальных людей. Это значит, что остальные люди непохожи на нас. Об этом стоит помнить во время общения с неинженерами. Всегда следует понимать свою аудиторию. + +Неинженеры умны, но не так связаны с созданием технических вещей, как мы. Мы создаем продукт. Они продают его, работают с ним, поддерживают и управляют, но они не эксперты в создании. Они не так хороши в командной работе, как инженеры (здесь, вне всяких сомнений, есть исключения). Их социальные навыки как правило так же хороши или лучше, чем у инженеров вне рабочей обстановки, но их работа не всегда требует того доверительного и точного общения и четкого распределения задач как у программистов. + +Неинженеры могут слишком стремиться угодить. Они могут смущаться при разговоре с вами. Подобно нам, они могут без реального понимания сказать "да", чтобы угодить вам или из-за страха перед вами. И затем не выполнить свое обещание. + +Непрограммисты могут понимать технические аспекты, но у них нет того, что трудно даже для нас: технической экспертизы. Они понимают, как работает технология, но не могут понять, почему один способ займет три месяца, а другой три дня. (В конце концов, программисты все так же анекдотично плохи в оценке затрат). Это дает прекрасную возможность для синергии с ними. + +При разговоре с вашей командой вы, не думая, используете сокращения или сленг, которые гораздо короче и эффективнее, так как у всех вас схожий опыт с технологиями и вашим продуктом в частности. Потребуется приложить усилие, чтобы не использовать этот сленг с теми, у кого нет подобного опыта, особенно, если присутствуют члены вашей команды. Такой сленг создает стену между вами и остальными и даже хуже, заставляет их бессмысленно тратить время. + +С вашей командой базовый контекст и цели общения ясны и не нуждаются в частом повторении, вы фокусируетесь на деталях. С неинженерами нужен другой подход. Они могут не понимать то, что вы считаете разумеющимся. И поскольку вы считаете это очевидным и не объясняете детали, после разговора с неинженером вам может показаться, что вы прекрасно поняли друг друга, в то время как в действительности образовалось большое недопонимание. Вам следует предполагать, что будет недопонимание, и внимательно следить, где в разговоре оно может появиться. Постарайтесь, чтобы ваш собеседник повторил или переформулировал своими словами то, что вы ему сказали, чтобы убедиться, что он правильно все понял. Если у вас есть возможность часто встречаться с этим человеком, потратьте время, чтобы узнать, насколько эффективно вы выражаете себя и как вы можете это делать лучше. Если в общении возникает проблема, стремитесь изменить собственный подход вместо того, чтобы разочаровываться в подходе собеседников. + +Я обожаю работать с неинженерами. Это дает прекрасные возможности учить других и учиться самому. Вы можете подавать пример в смысле ясности и четкости в общении. Инженеры привыкли вносить порядок в хаос, вносить ясность в неразбериху, и неинженеры очень ценят это качество в нас. Поскольку мы владеем технической экспертизой и часто понимаем проблемы бизнеса, часто мы можем найти простое решение проблем. + +Иногда неинженеры из доброты и стремления принять правильное решение предлагают вещи, которые по их мнению сделают нашу жизнь проще, тогда как в действительности существует решение гораздо лучше, которое можно найти, объединив взгляд неинженера с вашей технической экспертизой. Я лично люблю экстремальное программирование, поскольку оно решает эту проблему неэффективности. Быстрое согласование оценки с идеей упрощает поиск новой идеи, которая представляет собой лучшее сочетание затрат и выгод. + +Следующее: [Продвинутый программист](../../3-Advanced) diff --git a/ru/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/ru/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..b71b698 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,15 @@ +# Как сохранять мотивацию +[//]: # (Version:1.0.0) +Замечателен и удивителен тот факт, что программисты высоко мотивированы желанием создавать прекрасное, полезное и удобное. Это желание не уникально для программистов и не универсально, но оно настолько распространено именно среди них, что отделяет эту профессию от остальных. + +У этого есть практические и важные последствия. Если программисты вынуждены делать что-то, что не является прекрасным, полезным или удобным, они начинают терять мотивацию. В создание уродливых, глупых и скучных вещей вкладывается много денег, но в конечном счете именно радость творчества приносит наибольший доход компании. + +Очевидно, существуют целые индустрии вокруг мотивационных техник, некоторые из которых применимы и для программистов. Среди таких я могу выделить: + +- Использовать наиболее подходящий язык программирования для конкретной задачи +- Искать возможности применить новые технологии, языки программирования и техники +- Стараться либо научить кого-то, либо научиться самому в каждом проекте, как был мал он ни был + +Наконец, если возможно, старайтесь измерять свой вклад в работу в том, что для вас персонально имеет значение. Например, когда я работаю над багами, число уже исправленных мною багов мне совершенно неинтересно, ведь оно не зависит от общего числа багов, которые все еще возможно существуют. Кроме того, это число отражает мой вклад в самом малом из всех возможных ракурсов. Но соотносить каждый исправленный баг со счастливым клиентом для меня, наоборот, очень ценно, и служит мотивацией в работе. + +Следующее: [Как заслужить доверие](02-How-to-be-Widely-Trusted.md) diff --git a/ru/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md b/ru/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md new file mode 100644 index 0000000..96657ef --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -0,0 +1,7 @@ +# Как заслужить доверие +[//]: # (Version:1.0.0) +Чтобы вам доверяли, вы должны заслуживать доверия. Вы также должны быть на виду. Если никто не знает вас толком, то никто до конца вам не поверит. С теми, кто близок к вам, например, с вашими коллегами по команде, такой проблемы не будет. Заслужить доверие за пределами своего отдела или команды можно будучи отзывчивым и информативным. Иногда кто-нибудь попробует злоупотребить этим доверием и попросит о необоснованных уступках. Не бойтесь, просто объясните, чем вам придется пожертвовать, чтобы выполнить просьбу. + +Не притворяйтесь, что знаете то, что вы на самом деле не знаете. С людьми, которые не являются частью вашей команды, вам придется четко объяснить разницу между ответами "не могу ответить на это сходу" и "не могу этого знать в принципе". + +Следующее: [Как балансировать процессорное время и память](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/ru/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md b/ru/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md new file mode 100644 index 0000000..c326233 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -0,0 +1,15 @@ +# Как балансировать процессорное время и память +[//]: # (Version:1.0.0) +Вы можете быть хорошим программистом, не заканчивая колледж, но вам не стать продвинутым разработчиком без базовых знаний теории сложности вычислений. Вам необязательно знать нотацию "большое О", но я лично считаю, что вам следует понимать разницу между "константным временем вычисления", "n log n" и "n в квадрате". Может быть, вы сможете интуитивно сбалансировать процессорное время и память без этого понимания, но если его нет, у вас не будет прочной основы для общения с вашими коллегами. + +При проектировании или изучении алгоритма важно понимать, что время выполнения алгоритма иногда представляет собой функцию от размера входных данных. В таком случае мы можем сказать, что худшее/ожидаемое/лучшее время на исполнение этого алгоритма это "n log n", если оно пропорционально размеру ($n$), умноженному на логарифм размера данных. Это обозначение и способ выражения можно применять и к памяти, занимаемой структурой данных. + +Для меня теория сложности вычислений так же прекрасна и глубока, как и физика, и ее небольшая часть здорово помогает в работе. + +Время (циклы процессора) и память можно сбалансировать за счет друг друга. Это отличный пример того, что программирование - это компромисс. Не всегда оно систематично. В общем виде, сэкономить память можно за счет большего числа вычислений. Обратно, число вычислений можно уменьшить с помощью кэширования, то есть, увеличения памяти, хранящей копии данных. Иногда время можно уменьшить, сохраняя больше информации в структуре данных. Как правило, это требует небольшого объема памяти, но может усложнить алгоритм. + +Улучшение компромисса между объемом памяти и скоростью вычислений часто может привести к кардинальному изменению одного из этих параметров. Перед тем, как начать работу, спросите себя, действительно ли то, что вы собираетесь улучшить, нуждается в этом. Работать с алгоритмами интересно, но не забывайте, что улучшение того, что не является проблемой, не принесет заметной разницы в программу и увеличит нагрузку на тестирование. + +В современных компьютерах память кажется дешевым ресурсом, потому что в отличие от процессорного времени вы не видите, как она используется, пока не исчерпаете целиком. Но тогда сбой может оказаться катастрофическим. Существуют и другие скрытые затраты на использование памяти, такие как ваш эффект на сторонние программы, который должен быть постоянным, и время на ее выделение и освобождение. Обдумайте эти моменты перед тем, как вы пожертвуете памятью ради ускорения. + +Следующее: [Как проводить стресс-тестирование](04-How-to-Stress-Test.md) diff --git a/ru/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md b/ru/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md new file mode 100644 index 0000000..5a02664 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -0,0 +1,13 @@ +# Как проводить стресс-тестирование +[//]: # (Version:1.0.0) +Стресс-тестирование это увлекательная вещь. Сначала кажется, что его цель - выяснить, будет ли система работать под нагрузкой. В действительности, обычно система работает под нагрузкой, но начинает отказывать в каких-то местах, если нагрузка достаточно большая. Я называю это "достичь потолка". Могут быть исключения, но почти всегда это "потолок". Смысл стресс-тестирования в том, чтобы выяснить, где находится этот потолок для системы, а потом понять, как его отодвинуть. + +План для стресс-тестирования следует разрабатывать на ранних стадиях проекта, так как часто он помогает в точности прояснить, что именно ожидается от системы. Две секунды на запрос веб-страницы это позорный провал или оглушительный успех? Достаточно ли 500 одновременных пользователей? Ответы зависят от системы, но перед началом ее проектирования их уже стоит знать. Чтобы быть полезным, стресс-тестирование должно достаточно хорошо имитировать действительную нагрузку. Вряд ли возможно смоделировать 500 одновременных хаотичных и непредсказуемых пользователей, используя многопоточность системы, но как минимум можно создать 500 симуляций и попытаться смоделировать некоторую часть того, что будут делать реальные пользователи. + +Во время стресс-тестирования начните с небольшой нагрузки и увеличивайте ее по одному параметру системы, например, по частоте входных запросов или по величине входных данных, пока вы не достигнете потолка системы. Если вы достигли его слишком рано, чтобы удовлетворить требованиям к системе, выясните, какой ресурс является узким местом в системе (как правило, сильно не хватает чего-то одного). Что это: память, процессор, операции чтения и записи, пропускная способность сети или задержка данных? Затем выясните, как вы можете отодвинуть потолок. Обратите внимание, что повышение потолка или увеличение нагрузки, с которой справляется система, может не помочь или даже снизить производительность для легконагруженной системы. Обычно производительность под большой нагрузкой важнее производительности под маленькой. + +Возможно, вам придется получить представление о нескольких разных параметрах системы, чтобы построить ее мысленную модель. Здесь не обойтись какой-то одной техникой. Например, логирование часто дает хорошую картину о реальном времени на исполнение команд между двумя событиями в системе, но если оно внедрено небрежно, то не дает понимания об использовании памяти или даже о размере структур данных. Аналогично, в современных системах могут взаимодействовать несколько компьютеров и множество программных систем. Когда вы упираетесь в потолок (то есть производительность нелинейно зависит от размера входных данных), эти сторонние программы могут оказаться узким местом. Представление о работе этих программ, даже в виде простого измерения загрузки процессоров на всех задействованных машинах, может оказаться очень полезным. + +Знать потолок системы важно не только для того, чтобы отодвинуть его, но и для обеспечения предсказуемости, чтобы эффективно управлять связанными с системой бизнес-процессами. + +Следующее: [Как балансировать краткость и абстракцию](05-How-to-Balance-Brevity-and-Abstraction.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md b/ru/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md new file mode 100644 index 0000000..8be4c0c --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -0,0 +1,9 @@ +# Как балансировать краткость и абстракцию +[//]: # (Version:1.0.0) +Абстракция - это основа программирования. Следует тщательно выбирать, насколько абстрактным вам следует быть. Начинающие программисты в своем энтузиазме часто создают больше абстракций, чем в действительности необходимо. Один из признаков такой ситуации: вы создаете классы, которые почти не содержат код и служат только для абстрактного представления чего-то. Привлекательность этого подхода понятна, но ценность краткости кода надо соизмерять с ценностью абстракции. Иногда можно видеть ошибку, совершаемую восторженными идеалистами: на старте проекта создается множество классов, которые кажутся восхитительно абстрактными, и кажется, что они справятся со всеми ситуациями, которые только могут возникнуть. По мере продвижения проекта и наступления усталости код становится беспорядочным. Тела функций становятся больше, чем они должны быть. Пустые классы это еще и бремя документирования, которое часто игнорируется под давлением. Итоговый результат был бы лучше, если бы энергия, потраченная на абстракцию, была бы потрачена на то, чтобы сохранить код кратким и простым. Это разновидность *спекулятивного программирования*. На эту тему я очень рекомендую прочесть статью Пола Грэхема ['Succinctness is Power'](http://www.paulgraham.com/power.html). + +Существует определенные догмы, связанные с такими полезными техниками как *сокрытие информации* и *объектно-ориентированное программирование*, применение которых иногда заходит слишком далеко. Они позволяют писать код более абстрактно и предвидеть возможные в нем изменения. Однако, я лично считаю, что не следует писать слишком много спекулятивного кода. Например, принято прятать целочисленные переменные в объектах за публичными методами класса, так что сама переменная не видна, а доступен только интерфейс к ней. Это позволяет изменить реализацию этой переменной без изменения вызывающего эти методы кода. Возможно, это подходит для разработки библиотек, где необходимо предоставить устойчивый API. Но я не думаю, что преимущества этого подхода перевешивают избыток кода, потраченного на него, особенно, когда моя команда владеет вызывающим кодом и может переписать как его, так и вызываемый код. Четыре или пять строк кода - это большая цена за такое умозрительное преимущество. + +Портируемость создает похожую проблему. Должен ли код быть портируемым на другой компьютер, компилятор, систему или платформу, или его стоит просто переписать под них? Я думаю, что непортируемый, короткий и легко переписываемый код лучше, чем длинный портируемый. Относительно легкая и обычно хорошая идея - ограничить непортируемый код в определенных областях, таких как класс, который выполняет запросы к базе данных, специфичные для данной СУБД. + +Следующее: [Как осваивать новые навыки](06-How-to-Learn-New-Skills.md) diff --git a/ru/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md b/ru/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md new file mode 100644 index 0000000..d7cd842 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -0,0 +1,13 @@ +# Как осваивать новые навыки +[//]: # (Version:1.0.0) +Учить новое, особенно что-то нетехническое, это величайшее удовольствие из всех. Большинство компаний имели бы гораздо лучшую мораль в коллективе, если бы они понимали, как учеба мотивирует программистов. + +Люди учатся на практике. Чтение книг и курсы полезны, но сможете ли вы уважать программиста, который никогда не писал программы? Чтобы чему-нибудь научиться, вы должны поставить себя в положение, когда вы можете применять этот навык. Изучая новый язык программирования, попытайтесь выполнить на нем маленький проект перед тем, как вам придется использовать этот язык в большом проекте. Осваивая управление проектом по разработке программного обеспечения, сначала попробуйте руководить небольшим проектом. + +Хороший учитель не заменит практику, но гораздо лучше книги. Что вы можете предложить потенциальному учителю в обмен на его знания? Как минимум, вы можете предложить усердно учиться, так что время этого человека не будет потрачено впустую. + +Постарайтесь уговорить своего босса оплатить вам формальное обучение, но помните, что чаще всего гораздо полезнее потратить то же время на свободную игру с тем навыком, который вы хотите освоить. Однако, в нашем несовершенном мире легче попросить об обучении, чем о времени на свободное полуизучение-полуигру, хоть множество формальных обучений и сводятся ко сну на лекциях в ожидании обеда. + +Если вы руководитель, постарайтесь понять, как учатся ваши подчиненные и помогите им, назначая им такие проекты и задания, которые им по плечу и одновременно позволят развить интересные им навыки. Не забывайте, что самые важные навыки программиста вовсе не технические. Дайте своей команде время экспериментировать и практикуйте в команде смелость, честность и взаимодействие. + +Следующее: [Научитесь печатать вслепую](07-Learn-to-Type.md) diff --git a/ru/2-Intermediate/Personal-Skills/07-Learn-to-Type.md b/ru/2-Intermediate/Personal-Skills/07-Learn-to-Type.md new file mode 100644 index 0000000..3049d62 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -0,0 +1,5 @@ +# Научитесь печатать вслепую +[//]: # (Version:1.0.0) +Научитесь печатать вслепую. Это навык среднего уровня, потому что писать код настолько сложно, что скорость его набора неважна и несильно влияет на затраченное время на разработку, насколько бы хорошим программистом вы не являлись. Однако, к тому времени, как вы станете программистом среднего уровня, скорее всего вы потратите кучу времени на письменное общение с коллегами и всеми остальными. Этот навык - интересная проверка вашей целеустремленности. Он требует посвятить на себя отдельное время, которое вовсе не так интересно потратить именно на него. Легенда гласит, что когда Майкл Тименн работал в Microelectronics and Computer Technology Corporation, его коллеги собирались у двери его кабинета послушать гул, производимый им при нажатии клавиш. Они были настолько быстры, что были практически неразличимы. + +Следующее: [Как проводить интеграционное тестирование](08-How-to-Do-Integration-Testing.md) diff --git a/ru/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md b/ru/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md new file mode 100644 index 0000000..52436b4 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -0,0 +1,7 @@ +# Как проводить интеграционное тестирование +[//]: # (Version:1.0.0) +Интеграционное тестирование - это совместное тестирование отдельных компонентов, которые прошли до этого юнит-тестирование. Интеграция обходится дорого, и это выясняется при тестировании. Вы должны включать время на интеграционное тестирование в свои оценки затрат и в график работ. + +В идеале вы должны организовать проект таким образом, чтобы в конце не было отдельного этапа, где явным образом должна происходить интеграция. Гораздо лучше постепенно интегрировать компоненты по мере их завершения в ходе проекта. Если такой этап неизбежен, тщательно оцените временные затраты на него. + +Следующее: [Communication Languages](09-Communication-Languages.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Personal-Skills/09-Communication-Languages.md b/ru/2-Intermediate/Personal-Skills/09-Communication-Languages.md new file mode 100644 index 0000000..47a0bb6 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -0,0 +1,11 @@ +# Языки взаимодействия систем +[//]: # (Version:1.0.0) +Существуют языки, то есть формально определенные синтаксические системы, которые являются не языками программирования, а языками взаимодействия систем, созданными специально для облегчения взаимодействия через стандартизацию. В 2003 году самые важные из них это UML, XML и SQL. Вы должны быть знакомы с каждым из них, чтобы уметь использовать их и понимать, когда их следует применять. + +UML - это обширная формальная система для создания схем и диаграмм, описывающих архитектуру. Ее прелесть в том, что она одновременно и визуальна, и формальна, и способна передать огромное количество информации, если автор и его аудитория понимают UML. Вам следует знать UML, потому что иногда архитектуру описывают с ее помощью. Существуют очень полезные инструменты для создания профессионально выглядящих схем UML. Во многих случаях, UML слишком строгая и формальная система, и я иногда находил, что для архитектурных схем проще использовать стрелки и прямоугольники. Но я уверен, что изучение UML полезно так же, как и изучение латыни. + +XML - это стандарт для определения новых стандартов. Это не решение проблем передачи данных, хотя иногда вы увидите, что XML представляют именно так. Но скорее, это средство автоматизации самой скучной работы по обмену данных, а именно структурное представление данных в линейной последовательности и обратное преобразование этой последовательности в структуру данных. UML предоставляет неплохую проверку типов и правильности данных, хотя это лишь небольшая часть того, что вам понадобится в работе. + +SQL - это очень мощный и богатый язык запросов и манипулирования данными. Это не совсем язык программирования. У него есть много вариаций, в основном зависимых от конкретного продукта, который его использует. Они не так важны как стандартное ядро языка. SQL - это основа всех реляционных баз данных. Вы можете не работать в области, где требуется понимание такого типа баз данных, но вам все равно следует иметь базовое представление о них, о синтаксисе и о назначении SQL. + +Следующее: [Стандартные технологии](10-Heavy-Tools.md) diff --git a/ru/2-Intermediate/Personal-Skills/10-Heavy-Tools.md b/ru/2-Intermediate/Personal-Skills/10-Heavy-Tools.md new file mode 100644 index 0000000..4585f86 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -0,0 +1,14 @@ +# Стандартные технологии + [//]: # (Version:1.0.0) +По мере того, как развиваются технологии, разработка программного обеспечения переходит к использованию стандартизированных, широко распространенных и незатратных технологий. Они могут взять на себя большую нагрузку в разработке программного обеспечения, но одновременно могут показаться пугающе непонятными и требовать много времени на освоение. Программист среднего уровня должен знать, как управлять этими технологиями и когда следует их использовать. + +На мой взгляд некоторыми примерами таких технологий являются: + +- Реляционные базы данных +- Полнотекстовые поисковые системы +- Математические библиотеки +- OpenGL +- XML-парсеры +- Электронные таблицы + +Следующее: [Как анализировать данные](11-How-to-analyze-data.md) diff --git a/ru/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md b/ru/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md new file mode 100644 index 0000000..eb44dc6 --- /dev/null +++ b/ru/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -0,0 +1,13 @@ +# Как анализировать данные +[//]: # (Version:1.0.0) +Анализ данных - это ранний этап разработки, когда вы изучаете предметную область и определяете требования для их преобразования в программное обеспечение. Это формальное определение может заставить подумать, что анализ данных это деятельность, которую стоит оставить на системных аналитиков. А программисты должны сосредоточиться на написании кода, который те спроектируют. Если мы строго последуем парадигме разработки, то возможно, это будет правильная идея. Опытные программисты становятся архитекторами, а лучшие архитекторы становятся бизнес-аналитиками и отвечают за требования к данным и выдают программистам четко определенное задание для написания кода. Но это не совсем так, так как данные это ядро любой деятельности программистов. Что бы вы не делали в своей программе, вы либо передаете, либо изменяете данные. Бизнес-аналитик изучает требования в широком виде, архитектор в чуть более узком разрезе, так что, когда проблема приходит к вам, кажется, что все, что вам надо сделать, это применить нужные алгоритмы и начать взаимодействовать с имеющимися данными. + +Это не так. + +Неважно, на каком этапе вы начинаете работать с данными, они всегда остаются главной заботой в хорошо спроектированном приложении. Если вы внимательно посмотрите, как бизнес-аналитик извлекает требования из запросов клиентов, то поймете, что данные играют фундаментальную роль. Аналитик создает так называемые диаграммы потоков данных, где указаны источники данных, и обозначен поток информации. Определив, какие данные будут частью системы, архитектор начнет формировать источники данных с точки зрения баз данных, протоколов обмена данными и форматов файлов. После этого задачу можно передавать программисту. Но процесс на этом не заканчивается, потому что вы (программист) даже после подобной тщательной обработки данных должны проанализировать их, чтобы выполнить задачу оптимальным способом. В основе вашей работы лежит идея Никлауса Вирта, создателя нескольких языков программирования. "Алгоритмы + Структуры данных = Программы". Алгоритм никогда не существует отдельно, делая что-то сам по себе. Каждый алгоритм обязательно взаимодействует как минимум с какой-то частью данных. + +Таким образом, раз алгоритмы не функционируют в вакууме, вы должны анализировать и данные, которые кто-то передал вам для разработки, и данные, которые надо воплотить в коде. Вот простой пример. Вы пишите программу для поиска книг в библиотеки. Согласно вашей спецификации пользователь может выбрать книги по сочетанию жанра, автора, названию, издателю, году издания и числу страниц. Конечная цель вашего модуля - создать корректный запрос SQL для отправки в базе данных. Основываясь на этих требованиях, вы можете выбирать варианты. Можно проверять каждый параметр по очереди, используя оператор "switch" или несколько последовательных "if". Можно создать массив параметров и проверять, есть ли в нем каждый параметр. Можно создать (или использовать) абстрактный объект для контроля данных, от которого унаследовать конкретные параметры и связать их с механизмом управления событиями. Если в требованиях есть настройка производительности запроса через проверку параметров в определенном порядке, то вы можете рассмотреть применение дерева компонентов для построения SQL-запроса. Как видно, выбор алгоритма зависит от данных, которые вы решите использовать или создать. Подобные решения часто отделяют эффективные алгоритмы от провальных. Однако, эффективность здесь не единственная проблема. Вы можете создать десяток переменных и сделать их максимально эффективными. Но такой код не будет легко поддерживаемым. Возможно, выбор подходящего контейнера для хранения всех ваших переменных поможет сохранить ту же скорость алгоритма и вдобавок сделает код более понятным для ваших коллег, когда они вернутся к нему в следующем году. Более того, хорошо выбранная структура данных позволит им легко расширить функциональность вашего кода без переписывания уже имеющихся частей. В конечном счете ваш выбор данных определяет, как долго просуществует ваш код. + +Еще один пример для размышлений. Предположим, у вас задача найти все слова в словаре с тремя и более анаграммами. При этом анаграмма должна быть другим словом в этом же словаре. Если вы будете думать об этой задаче, как о задаче на вычисление, то вы придете к бесконечным вычислениям в попытке вычислить все комбинации анаграмм для каждого слова и сравнить их со всеми остальными словами в словаре. Однако, анализируя исходные данные, вы можете заметить, что каждое слово можно представить как запись с самим словом и сортированным массивом из его букв в виде ID. С этим знанием нахождение анаграмм превращается в сортировку этого массива и нахождение слов с аналогичным ID. Прямой алгоритм может потребовать несколько дней на выполнение, тогда как более хитрый выполняется за несколько секунд. Вспомните этот пример, когда в следующий раз вы столкнетесь с неразрешимой проблемой. + +Следующее: [Командные навыки. Как управлять временем разработки](../Team-Skills/01-How-to-Manage-Development-Time.md) \ No newline at end of file diff --git a/ru/2-Intermediate/README.md b/ru/2-Intermediate/README.md new file mode 100644 index 0000000..537a370 --- /dev/null +++ b/ru/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. Программист среднего уровня +[//]: # (Version:1.0.0) +- Личные навыки + - [Как сохранять мотивацию](Personal-Skills/01-How-to-Stay-Motivated.md) + - [Как заслужить доверие](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [Как балансировать процессорное время и память](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [Как проводить стресс-тестирование](Personal-Skills/04-How-to-Stress-Test.md) + - [Как балансировать краткость и абстракцию](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [Как осваивать новые навыки](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Научитесь печатать вслепую](Personal-Skills/07-Learn-to-Type.md) + - [Как проводить интеграционное тестирование](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Языки взаимодействия систем](Personal-Skills/09-Communication-Languages.md) + - [Стандартные технологии](Personal-Skills/10-Heavy-Tools.md) + - [Как анализировать данные](Personal-Skills/11-How-to-analyze-data.md) +- Командные навыки + - [Как управлять временем разработки](Team-Skills/01-How-to-Manage-Development-Time.md) + - [Как управлять рисками, связанными со сторонним программным обеспечением](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [Как руководить консультантами](Team-Skills/03-How-to-Manage-Consultants.md) + - [Как соизмерять количество общения](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [Как честно выражать несогласие](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- Экспертиза + - [Как балансировать качество и время разработки](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [Как управлять зависимостями](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [Как оценивать стороннее программное обеспечение](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [Как решить: покупать программу или писать свою](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [Как расти профессионально](Judgment/05-How-to-Grow-zProfessionally.md) + - [Как проводить собеседования](Judgment/06-How-to-Evaluate-Interviewees.md) + - [Как понять, когда применять высокие технологии](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [Как разговаривать с неинженерами](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/ru/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md b/ru/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md new file mode 100644 index 0000000..1f21cfd --- /dev/null +++ b/ru/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -0,0 +1,11 @@ +# Как управлять временем разработки +[//]: # (Version:1.0.0) +Чтобы управлять временем разработки, поддерживайте четкий и актуальный проектный план. Проектный план - это оценка временных затрат, график, набор промежуточных этапов для отслеживания прогресса и распределение времени вашей команды на каждое задание. Он также должен включать другие вещи, о которых важно помнить: встречи с командой тестирования, подготовка документации, заказ рабочего оборудования. Если вы работаете в команде, проектный план должен быть согласованным решением, как на старте проекта, там и по его ходу. + +Проектный план служит для принятия решений, а не для демонстрации того, насколько вы организованы. Если он слишком подробный или неактуальный, к нему бесполезно обращаться для принятия решений. В реальности, все эти решения касаются отдельных людей. План и ваша экспертиза позволят вам понять, следует ли передать часть задач одного члена команды другому. Этапы проекта отмечают его прогресс. Если вы используете модный современный трекер задач для планирования проекта, не поддавайтесь соблазну сходу расписать большой предварительный план. Лучше используйте трекер, чтобы поддерживать емкость и актуальность задач. + +Если вы не успеваете выполнить этап, следует немедленно предпринять что-то, как минимум проинформировать босса о том, что запланированное завершение проекта сместится на некоторое время. Стоило бы начать с того, что оценка и расписание никогда не будут идеальны, но они дают иллюзию, что вы сможете наверстать пропущенные дни в конце проекта. Может быть. Но так же вероятно, что вы недооценили эту часть проекта, как и то, что вы ее переоценили. Так что запланированное завершение проекта уже сместилось, нравится вам это или нет. + +Убедитесь, что ваш план включает время на внутренние совещания команды, демонстрации проекта, документирование, периодические задачи по графику, интеграционное тестирование, общение с внешними командами, больничные, отпуска, поддержку существующих продуктов и окружения разработки. Проектный план можно показать сторонним людям или боссу, чтобы они поняли, чем занята команда. По этой причине он должен быть краток и актуален. + +Следующее: [Как управлять рисками, связанными со сторонним программным обеспечением](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/ru/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md b/ru/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md new file mode 100644 index 0000000..2e17b5d --- /dev/null +++ b/ru/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -0,0 +1,11 @@ +# Как управлять рисками, связанными со сторонним программным обеспечением +[//]: # (Version:1.0.0) +Проект часто зависит от стороннего программного обеспечения, над которым у вас нет контроля. С этим связаны большие риски, которые должны быть понятны каждому, кто работает в проекте. + +Никогда не возлагайте никаких надежд на якобы обещанное, но пока еще недоступное программное обеспечение. Это вернейший способ вылететь в трубу. Неразумно просто скептически относиться к обещанию сторонней компании выпустить определенный продукт к определенной дате. Гораздо разумнее полностью проигнорировать его и забыть о его существовании. Никогда не записывайте такие надежды в документы вашей компании. + +Если стороннее программное обеспечение все же существует, оно по-прежнему несет с собой риски, но по крайней мере эти риски можно преодолеть. Если вы предполагаете использование сторонних программ, уже на ранней стадии проекта следует посвятить время на их оценку. Никому не понравится услышать, что потребуется две недели, а то и два месяца на оценку пригодности всех трех сторонних программ, но это то, что надо сделать как можно раньше. Стоимость интеграции нельзя оценить без надлежащей оценки задействованных сторонних программ. + +Понимание пригодности существующих сторонних программ для конкретных задач - это очень отраслевое знание. Оно субъективно, и в основном им владеют эксперты. Вы можете сэкономить кучу времени, если сможете их найти. Часто проект настолько зависит от стороннего программного обеспечения, что если интеграция провалится, то провалится весь проект. Выразите все подобные риски в проектном плане. Постарайтесь иметь план на случай непредвиденных обстоятельств, например, альтернативные сторонние программы или возможность реализовать часть их функциональности самостоятельно. Никогда не вносите в график еще невыпущенное стороннее программное обеспечение. + +Следующее: [Как руководить консультантами](03-How-to-Manage-Consultants.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/ru/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..9320741 --- /dev/null +++ b/ru/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,9 @@ +# Как руководить консультантами +[//]: # (Version:1.0.0) +Используйте консультантов, но не полагайтесь на них. Эти замечательные люди заслуживают всяческого уважения. Поскольку они наблюдали множество проектов, они зачастую знают больше о специфических технологиях или даже техниках программирования, чем вы. Лучший способ использовать их - в качестве штатных преподавателей, которые могут научить на собственном примере. + +Однако, обычно консультанты не могут стать частью команды в том смысле, что и обычные сотрудники, хотя бы потому, что у вас может не хватить времени изучить их сильные и слабые стороны. Их финансовые обязательства гораздо ниже. Они могут легко уйти. Они меньше выигрывают, если компания в целом процветает. Некоторые из них будут хороши, некоторые средними, некоторые плохими консультантами. Поскольку ваш выбор консультантов будет не так тщателен, как подбор сотрудников, чаще вы будете встречать плохих. + +Если консультанты пишут код, то вы должны тщательно ревьюить его по мере работы. Нельзя доводить проект до конца, рискуя оставить непроверенным большой блок кода. Это относится ко всем членам команды, но обычно вы их знаете лучше, чем консультантов. + +Следующее: [Как соизмерять количество общения](04-How-to-Communicate-the-Right-Amount.md) \ No newline at end of file diff --git a/ru/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md b/ru/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md new file mode 100644 index 0000000..241810a --- /dev/null +++ b/ru/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -0,0 +1,7 @@ +# Как соизмерять количество общения +[//]: # (Version:1.0.0) +Тщательно соизмеряйте стоимость совещания. Оно равно *его длительности, умноженной на число участников*. Иногда совещания необходимы, но небольшие совещания лучше. Качество общения на небольших совещаниях лучше, и на них уходит меньше времени. Если на совещании кто-нибудь скучает, то это знак, что следующее собрание должно быть меньше. + +Необходимо следует все возможное, чтобы поощрять неформальное общение. Во время обеда с коллегами делается больше полезной работы, чем в любое другое время. Жаль, что многие компании не признают и не поддерживают этот факт. + +Следующее: [Как честно выражать несогласие](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/ru/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md b/ru/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md new file mode 100644 index 0000000..d8ad7c1 --- /dev/null +++ b/ru/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -0,0 +1,11 @@ +# Как честно выражать несогласие +[//]: # (Version:1.0.0) +Несогласие это прекрасная возможность принять хорошее решение, но его следует выражать аккуратно. Надеюсь, обычно вы спокойно выражаете свою точку зрения, вас внимательно слушают, а затем принимается решение. В этом случае больше нечего сказать, и вам только остается решить, поддерживать ли решение несмотря на свое несогласие с ним. Если вы все же можете поддержать решение, с которым вы несогласны, скажите об этом. Так вы покажете свою ценность: вы независимы, имеете свое мнение и не идете на поводу, но одновременно уважаете принятое решение и всю команду. + +Иногда решение, с которым вы несогласны, принимается потому, что те, кто его принимает, не имели возможности полностью оценить ваше мнение. В этом случае, исходя из пользы для компании или команды вам стоит прикинуть, поднимать ли вопрос. Если это небольшая на ваш взгляд ошибка, то, возможно, не стоит пересматривать решение. Если же речь идет о серьезной ошибке, то стоит выдвинуть возражения. + +Обычно возражения это не проблема. В некоторых стрессовых ситуациях и с некоторыми типами личностей их могут принять на личный счет. Например, некоторые очень хорошие программисты недостаточно уверены в себе, чтобы возразить, даже если у них на это есть веские причины. В худшем случае, тот, кто принимает решения неуверен в себе и принимает возражения как вызов своему авторитету. Здесь важно помнить, что в таких обстоятельствах люди в первую очередь реагируют инстинктивно. Вам стоит высказать свои возражения наедине с этим человеком и постараться показать, как новые аргументы изменят основу, на которой принимается решение. + +Независимо от того, будет решение отменено или нет, вы должны помнить, что вы не сможете сказать "Я же говорил!", поскольку альтернативное решение было полностью изучено. + +Следующее: [Экспертиза. Как балансировать качество и время разработки](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/ru/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md b/ru/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md new file mode 100644 index 0000000..519eefd --- /dev/null +++ b/ru/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -0,0 +1,11 @@ +# Как справляться с давлением графика +[//]: # (Version:1.0.0) +Давление выхода на рынок - это необходимость быстро выпустить хороший продукт. Это хорошо, поскольку отражает финансовую действительность, и до некоторой степени это полезное давление. Давление графика - это давление выпустить что-то быстрее, чем это возможно, и подобное давление опустошает, оно нездоровое и встречается слишком часто. + +Давление графика существует по нескольким причинам. Люди, дающие задания программистам не до конца ценят нашу рабочую этику и любовь к профессии. Возможно, поскольку они проецируют собственное поведение на нас, они ожидают, что просьба сделать задачу быстрее заставит нас работать усерднее. Возможно, это так, но эффект от такой просьбы очень мал, а ущерб велик. Вдобавок, они не понимают, что в действительности значит разработать программное обеспечение. Они не могут этого понять, не могут разработать систему самостоятельно, поэтому единственное, что им остается, это наблюдать за давлением выхода на рынок и подталкивать программистов. + +Лучшее, что можно сделать с давлением графика, это превратить его в давление выхода на рынок. Для этого надо дать четкое представление о связи между имеющимися затратами и продуктом. Лучший способ - это дать честную, детальную и, самое главное, понятную оценку всех трудозатрат. Это дает дополнительное преимущество в виде возможности принимать правильные управленческие решения насчет возможных компромиссов в функциональности. + +Ключевая мысль, которую должна прояснить оценка, заключается в том, что работа очень похожа на несжимаемую жидкость. Вы не можете вместить в промежуток времени больше работы, так же как не можете вместить в контейнер больше воды, чем его объем. В некотором смысле, программист должен не говорить "Нет", а спрашивать в ответ "Чем вы готовы пожертвовать, чтобы эта работа была сделана?". Эффект от составления четких планов и оценок заключается в повышении уважения к программистам. Именно так ведут себя профессионалы. Усердная работа программистов станет видна, а нереалистичный график станет для всех очевиден. Программистов нельзя провести. Нереалистичный график это неуважение к команде, он сильно деморализует людей. Экстремальное программирование расширяет эту идею и строится вокруг нее. Я надеюсь, что каждому из читателей посчастливится использовать его в работе. + +Следующее: [Как понять пользователя](02-How-to-Understand-the-User.md) \ No newline at end of file diff --git a/ru/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md b/ru/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md new file mode 100644 index 0000000..768efbb --- /dev/null +++ b/ru/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -0,0 +1,17 @@ +# Как понять пользователя +[//]: # (Version:1.0.0) +Ваша обязанность - это понять пользователя и помочь это сделать вашему боссу. Поскольку пользователи непосредственно не вовлечены в разработку вашего продукта, они ведут себя слегка иначе: + +- Обычно пользователи выносят короткие суждения или заявления +- У пользователей есть своя работа, они будут скорее думать о небольших доработках в вашем продукте, чем о больших улучшениях +- Мнение одного конкретного пользователя не может представлять общее мнение всех пользователей вашего продукта + +Ваша обязанность - дать пользователям не то, что они говорят, что хотят, а то, что они хотят в действительности. Однако, лучше всего это сформулировать и получить от ваших пользователей ответ, что ваше предложение действительно отвечает их реальным желаниям. Хотя у пользователей может не хватит полного понимания всей картины для ответа. Ваша уверенность в собственных идеях на этот счет должна варьироваться. Следует одинаково опасаться как самоуверенности, так и ложной скромности, когда речь идет о нуждах вашего пользователя. Программисты нацелены на проектирование и создание. Исследователи рынка нацелены на выявление нужд потребителей. Эти два типа людей или два типа мышления в одном человеке, гармонично работая в связке, дают наилучший шанс сформировать правильное понимание пользователя. + +Чем больше времени вы проведете с пользователями, тем лучше вы сможете понять, что будет лучшим для них. Вам стоит проверять свои идеи на пользователях так часто, насколько это вообще возможно. Вам стоит обедать с ними, если это возможно. + +Гай Кавасаки [Rules] подчеркивает важность *наблюдения* того, чем заняты ваши пользователи, дополнительно к выслушиванию их пожеланий. + +Я думаю, что у подрядчиков и консультантов часто возникают большие проблемы с тем, чтобы их клиенты прояснили в своем сознании, что они хотят в действительности. Если вы намерены быть консультантом, я бы предложил вам выбирать клиентов по четкости их мыслей и по кошельку. + +Следующее: [Как получить повышение](03-How-to-Get-a-Promotion.md) \ No newline at end of file diff --git a/ru/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md b/ru/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md new file mode 100644 index 0000000..176e94e --- /dev/null +++ b/ru/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -0,0 +1,13 @@ +# Как получить повышение +[//]: # (Version:1.0.0) +Чтобы получить повышение по роли, начните играть эту роль. + +Чтобы получить повышение по должности, выясните, что ожидается от этой должности, и делайте это. + +Чтобы получить прибавку к зарплате, обговорите ее, имея на руках веские аргументы в свою пользу. + +Если вы чувствуете, что вас обошли с повышением, поговорите с боссом об этом. Спросите его в явном виде, что вы должны делать, чтобы получить повышение, и постарайтесь сделать это. Это кажется банальным, но часто ваше представление того, что вам надо делать, отличается от представления вашего босса. Кроме того, такой разговор в некотором смысле подтолкнет вашего босса. + +Большинство программистов скорее всего имеют преувеличенное представление о собственных способностях. В конце концов, мы все не можем входить в 10% лучших программистов. Однако, я встречал и людей, которые были очень сильно недооценены. Нельзя ожидать, что оценка каждого будет на 100% совпадать с реальностью, но я думаю, что в общем люди довольно справедливо себя оценивают. С одной оговоркой: вас нельзя справедливо оценить без видимости вашей работы. Иногда из-за обстоятельств или личных качеств кто-то будет не настолько сильно заметен. Работа из дома или географически удаленно от вашей команды и босса делает это особенно трудным. + +Следующее: [Управление командой. Как развивать таланты](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/ru/3-Advanced/README.md b/ru/3-Advanced/README.md new file mode 100644 index 0000000..c0b4f7b --- /dev/null +++ b/ru/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. Продвинутый программист +[//]: # (Version:1.0.0) +- Техническая экспертиза + - [Как отличить сложное от невозможного](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [Как использовать встроенные языки](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Выбор языка программирования](Technical-Judgment/03-Choosing-Languages.md) +- Правильные компромиссы + - [Как справляться с давлением графика](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [Как понять пользователя](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [Как получить повышение](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- Управление командой + - [Как развивать таланты](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [Как выбрать, над чем работать](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [Как получить наибольшую отдачу от коллег](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [Как разделять задачи](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [Как распределять скучные задания](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [Как получить поддержку для проекта](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [Как развивать систему](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [Как качественно взаимодействовать](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [Как сообщать неприятное](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [Как справляться с менеджерскими мифами](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [Как справляться с организационным хаосом](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/ru/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md b/ru/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md new file mode 100644 index 0000000..085e239 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -0,0 +1,23 @@ +# Как развивать таланты + +Ницше преувеличил, когда сказал[Stronger]: + +> Всё, что меня не убивает, делает меня сильнее. + +Ваша самая главная ответственность - это ваша команда. Вы должны хорошо знать каждого из членов команды. Вы должны нагружать свою команду, но не перегружать. Следует разговаривать с членами команды об их нагрузке. Если они согласны с ней, то они будут хорошо мотивированы. В каждом проекте старайтесь нагружать их таким образом, чтобы они были согласны со своей нагрузкой, и одновременно, чтобы она совпадала с вашим собственным мнением о том, что нужно членам вашей команды. Нагружайте их не объемом работы, а освоением новых навыков или слегка иной ролью в команде. + +Вам следует позволять людям (и себе тоже) иногда ошибаться. Предусматривайте эти неудачи в графике. Если ошибки и неудачи никогда не случаются, то нет и чувства приключения. Если иногда в работе нет ошибок и неудач, значит, вы недостаточно стараетесь. Когда кто-то ошибается, вам следует вести себя так вежливо, как вы можете, одновременно не относясь к человеку так, словно он преуспел. + +Постарайтесь вовлечь и увлечь каждого из членов команды. Спросите каждого из них в явном виде, что им нужно для мотивации, если они еще не мотивированы. Возможно, вы не сможете удовлетворить всех, но все же стоит узнать, кто что хочет. + +Нельзя мириться с членом команды, который намеренно не тянет свою часть нагрузки из-за низкого морального духа или неудовлетворенности. Нельзя позволять отлынивать. Вы должны стараться привести таких людей в состояние высокой мотивации и продуктивности. Пока у вас хватает терпения, подталкивайте их в этом направлении. Когда ваше терпение иссякнет, увольняйте их. Нельзя позволять тому, кто намеренно работает ниже своего уровня, оставаться в команде. Это несправедливо по отношению к остальным. + +Говорите публично сильным членам своей команды, что по вашему мнению они сильные сотрудники. Хвалите публично и критикуйте наедине. + +Более сильные члены вашей команды естественно будут заняты более трудными задачами, чем слабые. Это абсолютно нормально, и пока все в команде работают усердно, никто не должен заморачиваться по этому поводу. + +Странный факт, который не отражается на зарплатах, заключается в том, что хороший программист продуктивнее 10 плохих. Это порождает странную ситуацию. Часто будет случаться, что вы будете быстрее продвигаться по графику, если отстраните от работы всех слабых членов команды. Если бы вы так поступили бы, то действительно в краткосрочной перспективе вы добились бы большего прогресса. Однако, ваша команда потеряет несколько важных преимуществ, а именно обучение слабых членов команды, распространение знаний и способность команды восстанавливаться при потере сильных программистов. Сильные программисты должны быть снисходительными в этом плане и стараться видеть общую картину. + +Часто вы можете дать более сильным членам команды сложные, но тщательно разграниченные задачи. + +Следующее: [Как выбрать, над чем работать](02-How-to-Choose-What-to-Work-On.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md b/ru/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md new file mode 100644 index 0000000..046f8a2 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -0,0 +1,5 @@ +# Как выбрать, над чем работать + +Вы балансируете свои собственные потребности с потребностями команды через выбор того аспекта проекта, над которым вы работаете. Вам следует делать то, что у вас получается лучше всего, но ищите способы занять себя не увеличением работы, а применением новых навыков. Лидерство и навыки общения более важны, чем технические навыки. Если вы очень сильный программист, берите на себя самые сложные или рискованные задачи и выполняйте их как можно раньше, чтобы снизить риски. + +Следующее: [Как получить наибольшую отдачу от коллег](03-How-to-Get-the-Most-From-Your-Teammates.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md b/ru/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md new file mode 100644 index 0000000..8dfd82e --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -0,0 +1,15 @@ +# Как получить наибольшую отдачу от коллег + +Чтобы получить наибольшую отдачу от коллег, развивайте дружеский командный дух и старайтесь, чтобы каждый был лично востребован и вовлечен. + +В развитии командного духа помогают такие банальные штуки как одежда с лого компании и корпоративы, но нет ничего лучше личного взаимоуважения. Если все уважают друг друга, то никто никого не захочет подводить. Командный дух появляется, когда люди жертвуют ради команды и думают в рамках блага для всей команды, а не о личной выгоде. Как лидер, вы не можете требовать от остальных большего, чем лично вы делаете в этом отношении. + +Одним из ключевых моментов в руководстве команды является достижение консенсуса, так чтобы все были вовлечены в решение. Иногда это означает позволить своей команде ошибиться. То есть, если это не принесет большого ущерба проекту, вы должны позволить части своей команды поступать по-своему, основываясь на консенсусе, даже вы абсолютно уверены, что это неверное решение. В этом случае не надо соглашаться с коллегами, просто открыто выразите свое несогласие и примите общее решение. Не стоит говорить обиженно или так, как будто вы вынуждают к решению, просто обозначьте, что вы несогласны, но для вас решение команды гораздо важнее. Часто это заставит команду изменить свое решение. В этом случае, не заставляйте ее следовать первоначальному плану. + +Если найдется человек, который не согласится с вами после того, как вы рассмотрите проблему со всех сторон, просто скажите, что вам надо принять решение, и это ваше решение. Если есть возможность проверить, было ли ваше решение ошибочным или позднее окажется, что оно ошибочно, измените его, как только сможете, и признайте правоту тех, кто был с вами несогласен. + +Спросите свою команду как в группе, так и индивидуально по отдельности, что по их мнению создает командный дух и делает команду эффективной. + +Хвалите часто, но не много. Особенно хвалите тех, кто не согласен с вами, если в итоге они заслуживают похвалы. Хвалите публично и критикуйте наедине. Одно исключение: иногда прогресс или исправление ошибки нельзя отметить без упоминания виновника ошибки, в этом случае хвалите наедине. + +Следующее: [Как разделять задачи](04-How-to-Divide-Problems-Up.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md b/ru/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md new file mode 100644 index 0000000..3ef958e --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -0,0 +1,9 @@ +# Как разделять задачи + +Брать проект по разработке программного обеспечения и делить его на индивидуальные задачи - это увлекательно. Это стоит делать на ранних этапах. Иногда менеджеры склонны думать, что оценку затрат можно сделать без учета людей, которые будут выполнять задачи. Но это невозможно, так как продуктивность людей очень различается. Человек, обладающий конкретными знаниями о компоненте системы, также постоянно меняется, и это влияет на производительность. + +Подобно композитору, который учитывает тембр инструмента, играющего партию, или тренеру спортивной команды, держащему в уме сильные стороны каждого игрока, опытный руководитель не сможет отделить разделение проекта на задачи от членов команды, которые будут заниматься этими задачами. Это одна из причин, по которой высокоэффективную команду не стоит разбивать на части. + +В этом есть определенная опасность, что люди начнут скучать, так как такие команды основаны на сильных сторонах каждого. В этом случае члены команды не улучшают свои слабые стороны и не развивают новые навыки. Однако, специализация очень эффективна для производительности, если ею не злоупотреблять. + +Следующее: [Как распределять скучные задания](05-How-to-Handle-Boring-Tasks.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md b/ru/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md new file mode 100644 index 0000000..281b917 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -0,0 +1,7 @@ +# Как распределять скучные задания + +Иногда невозможно избежать скучных задач, которые критичны для успеха компании или проекта. Такие задания могут сильно подорвать дух тех, кому придется ими заниматься. Лучше всего постраться найти способ заставить компьютер выполнять эти задачи вместо ваших коллег, либо заставить его помочь им. Работа в течение недели над программой, выполняющей задачу, которая вручную займет ту же неделю, имеет то огромное выгоду, что она учит большему и иногда более повторяемая. + +Если ничего из этого не сработает, извинитесь перед теми, кому придется делать скучные задачи, но ни при каких обстоятельствах не позволяйте заниматься ими в одиночку. Как минимум назначьте двоих на эту работу и поощряйте командную работу в выполнении таких задач. + +Следующее: [Как получить поддержку для проекта](06-How-to-Gather-Support-for-a-Project.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md b/ru/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md new file mode 100644 index 0000000..6141b54 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -0,0 +1,5 @@ +# Как получить поддержку для проекта + +Чтобы получить поддержку для проекта, создайте и распространите его визуальный образ, который покажет реальную ценность проекта для организации в целом. Попытайтесь вовлечь других в создание образа вашего проекта. Это даст им причину поддерживать вас, а вам - возможность использовать их идеи. Индивидуально привлекайте ключевых людей для поддержки вашего проекта. Всегда, когда возможно, показывайте, а не рассказывайте. Если это реально, постройте прототип или макет для демонстрации ваших идей. Прототип всегда мощное средство, особенно для программного обеспечения, где он превосходит любое письменное описание. + +Следующее: [Как развивать систему](07-How-to-Grow-a-System.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md b/ru/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md new file mode 100644 index 0000000..c4dfef2 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -0,0 +1,23 @@ +# Как развивать систему + +Семя содержит в себе идею дерева, но не имеет форму и мощь взрослого растения. Семя вырастает в саженец. Он становится больше. Он все больше похож на взрослое дерево. Дерево начинает приносить плоды. Наконец, оно умирает и служит пищей для других организмов. + +У нас есть роскошь относиться к программному обеспечению похожим образом. Мост не похож на программное обеспечение. Не бывает мостов-детей, бывают недостроенные мосты. Они гораздо проще, чем программное обеспечение. + +Полезно думать о программном обеспечении как о чем-то растущем, это позволяет нам добиться существенного прогресса до того, как у нас сложится идеальный мысленный образ того, что мы делаем. Мы можем использовать обратную связь от пользователей, чтобы скорректировать развитие системы. Всегда полезно обрезать слабые и ненужные ветки. + +Программист должен разработать законченную систему, которую можно поставлять и использовать. Но продвинутый программист должен гораздо больше. Вы должны разработать путь развития, который завершится готовой системой. Ваша работа - взять зародыш идеи и построить путь, который как можно плавнее приведет к полезному продукту. + +Чтобы это сделать, вы должны визуализировать конечный результат и представить его так, чтобы ваша инженерная команда загорелась им. Но кроме этого вы должны рассказать им без больших пробелов весь путь, который ведет от текущей точки проекта до конечной. Дерево должно жить все это время, нельзя позволить ему умереть, а затем возрождать его. + +Этот подход отражен в спиральной разработке. Этапы проекта никогда не находятся далеко друг от друга и отмечают прогресс по пути проекта. В сверхконкурентной среде бизнеса лучше всего, если после каждого этапа программное обеспечение можно выпустить и заработать на этом денег, даже если оно все еще далеко от финального состояния. Одна из задач программиста - сбалансировать немедленную отдачу от проекта с будущей, тщательно выбирая путь прогресса, отраженный в его этапах. + +Продвинутый программист несет тройную ответственность за развитие программного обеспечение, команд и отдельных людей. + +Один из читателей, Роб Хаферник, прислал комментарий к этой части, который я не могу не привести полностью: + +> Я думаю, что вы недооценили важность этого вопроса. Он касается не только системы, но и алгоритмов, пользовательских интерфейсов, моделей данных и так далее. При работе над большой системой жизненно важно иметь измеряемый прогресс в достижении промежуточных целей. Ничто не сравнится с ужасом, когда вы доходите до конца и обнаруживаете, что все это просто не работает. Я бы пошел дальше и сформулировал бы это как природный закон: нельзя с листа построить большую и сложную систему. Ее можно только развить из небольшой в сложную через серию последовательных шагов. + +На это можно только ответить "Истинно так!" + +Следующее: [Как качественно взаимодействовать](08-How-to-Communicate-Well.md) diff --git a/ru/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md b/ru/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md new file mode 100644 index 0000000..8f23481 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -0,0 +1,11 @@ +# Как качественно взаимодействовать + +Чтобы качественно взаимодействовать, вам стоит осознать, насколько это трудно. Это сам по себе отдельный навык. Он усложняется тем, что люди, с которыми вам приходится взаимодействовать, несовершенны. Они не будут прилагать усилий, чтобы понять вас. Они плохо выражают свои мысли и плохо пишут. Они часто перегружены работой, либо им скучно, либо как минимум они больше сосредоточены на своей части работы, чем на глобальных проблемах, которые вы, возможно, решаете. Одно из преимуществ частных занятий и практики письма, публичных выступлений и слушания состоит в том, что если вы станете лучше во всем этом, вы сможете быстрее увидеть, где лежит проблема взаимодействия и как ее исправить. + +Программист - это социальное существо, и его выживание зависит от коммуникации с командой. Продвинутый программист - это социальное существо, чье удовлетворение зависит от коммуникации с людьми за пределами команды. + +Программисты приносят порядок в хаос. Один из интересных способов делать это - внести какое-нибудь предложение за пределами вашей команды. Это можно сделать в виде черновика или устно. Такой подход имеет огромное преимущество в том, что очерчивает рамки дискуссии. Он также ставит вас в позицию критикуемого и может привести к отказу и игнорированию. Продвинутый программист должен быть готов к этому, ведь у него есть уникальные возможности, а значит, и уникальная ответственность. Предприниматели, которые не являются программистами, нуждаются в том, чтобы программисты проявляли инициативу хоть в каком-то виде. Программисты - это та часть моста между идеями и действительностью, которая опирается на последнее. + +Я все еще не освоил до конца навык взаимодействия, но что я сейчас пытаюсь делать, можно выразить как четырехсторонний подход. После того, как я привожу свои идеи в порядок и полностью готов, я стараюсь сообщить о них устно, вручаю нужным людям черновой набросок (на бумаге или в электронном виде), показываю демо и затем терпеливо повторяю процесс. Я думаю, что часто мы недостаточно терпеливы для такого сложного общения. Не стоит расстраиваться, если ваши идеи не были приняты сразу. Если вы вложили много усилий в их подготовку, никто не будет думать о вас плохо из-за отказа. + +Следующее: [Как сообщать неприятное](09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) diff --git a/ru/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md b/ru/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md new file mode 100644 index 0000000..0ae6d52 --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -0,0 +1,9 @@ +# Как сообщать неприятное + +Часто вам придется говорить людям вещи, которые им не понравятся. Помните, что у вас есть на то причина. Даже если с проблемой ничего нельзя сделать, вы сообщаете о ней как можно раньше, чтобы все были информированы о ней. + +Лучший способ сообщить о проблеме - это тут же предложить способ ее решения. Второй хороший способ - это попросить о помощи в ее решении. Если есть опасность, что вам не поверят, соберите доказательства своей правоты. + +Одна из самых неприятных и частых фраз, которую вам придется произносить, это "График придется сдвинуть". Сознательный программист терпеть не может произносить ее, но должен делать это как можно раньше. Нет ничего хуже, чем откладывать решение, когда срывается этап проекта. Даже если решение заключается в информировании о проблеме. Когда такое происходит, лучше всего сказать это от лица команды. Вам понадобится мнение вашей команды о проблеме и том, как ее решить, а также участие команды в последствиях проблемы вместе с вами. + +Следующее: [Как справляться с менеджерскими мифами](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/ru/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md b/ru/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md new file mode 100644 index 0000000..67fc4fd --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -0,0 +1,13 @@ +# Как справляться с менеджерскими мифами + +Слово *миф* иногда означает вымысел. Но у него есть и более глубокий смысл. Оно также означает историю религиозного значения, которая объясняет вселенную и отношение человека к ней. Менеджеры склонны забывать, что они знали, когда были программистами, и верить в определенные мифы. Пытаться переубедить их, что эти мифы ложны, будет так же грубо и бессмысленно, как разубедить религиозного человека в его убеждениях. По этой причине вам следует различать как мифы следующие убеждения: + +- Больше документации всегда лучше. (Они хотят этого, но не хотят, чтобы вы тратили на это свое время) +- Программистов можно сравнивать. (Программисты очень сильно отличаются друг от друга) +- В проект можно добавить ресурсов, чтобы ускорить его. (Коммуникация с новыми людьми в проекте почти всегда скорее ведет к замедлению проекта, чем к ускорению) +- Разработку программного обеспечения можно надежно оценить по времени и затратам. (Это невозможно даже теоретически) +- Производительность программистов можно измерить одной простой метрикой, например, в строках кода. (Если качество в емкости, то избыточные строки кода это плохо, а не хорошо) + +Если у вас есть возможность, вы можете попытаться объяснить эти мифы, но не расстраивайтесь, если у вас не получится. Не портьте себе репутацию воинственным противостоянием этим мифам. Каждый из них поддерживает идею менеджеров о том, что у них есть реальный контроль над тем, что происходит в проекте. Но правда в том, что менеджеры только упрощают процесс, если они хороши, и мешают ему в противном случае. + +Следующее: [Как справляться с организационным хаосом](11-How-to-Deal-with-Organizational-Chaos.md) \ No newline at end of file diff --git a/ru/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md b/ru/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md new file mode 100644 index 0000000..e44c3ed --- /dev/null +++ b/ru/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md @@ -0,0 +1,11 @@ +# Как справляться с организационным хаосом + +Иногда случаются короткие периоды времени, когда царит организационный хаос: такие как массовые увольнения, покупка компании другой, размещение компании на бирже, массовый найм сотрудников и так далее. Такие времена неспокойны для всех, но возможно программистам здесь проще, так как их самооценка основана на чем-то большем, чем просто должность. Организационный хаос это прекрасная возможность для программистов проявить свою суперсилу. Я специально говорю об этом в самом конце эссе, потому что это тайна всех программистов. Если вы не программист, пожалуйста, прекратите чтение прямо сейчас. + +> Программисты могут создавать и поддерживать продукт. + +Неинженеры могут руководить людьми, но в типичной компании по разработке программного обеспечения они не могут ничего создать или поддерживать без инженеров. Точно так же типичные инженеры не смогут продать продукт или эффективно вести бизнес. Эта суперспособность защищает почти от всех проблем, связанных с временным организационным хаосом. Пока она с вами, вам следует игнорировать полностью хаос и продолжать делать свою работу, как будто ничего не происходит. Вас, конечно, могут уволить, но если это случится, то скорее всего вы найдете новую работу благодаря своей суперспособности. Но чаще всего кто-нибудь измученный стрессом придет к вам и прикажет делать что-нибудь глупое. Если вы совершенно уверены, что это глупо, то лучше всего улыбаться и кивать, пока этот человек не уйдет. А затем продолжать делать то, что вы считаете правильным для компании. + +Если вы лидер, скажите своей команде делать то же самое и игнорировать все, что ей будут говорить остальные. Такое поведение наиболее выгодно для вас лично и для всей компании или проекта. + +Следующее: [Глоссарий](../../GLOSSARY.md) diff --git a/ru/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/ru/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..9b024e2 --- /dev/null +++ b/ru/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# Как отличить сложное от невозможного +[//]: # (Version:1.0.1) +Ваша работа заключается в том, чтобы делать сложное и отличать невозможное. С точки зрения большинства программистов невозможное это то, что нельзя получить с помощью одной системы или то, что нельзя оценить. По этому определению научное исследование невозможно выполнить. Большой объем работы это сложно, но необязательно невозможно. + +Это нешуточное различие, потому что часто вас будут просить сделать то, что невозможно практически, будь то с научной точки зрения или с точки зрения разработки программного обеспечения. Тогда ваша задача помочь найти разумное решение, которое будет просто сложным и позволит реализовать большую часть запросов. Решение является сложным, если его можно с уверенностью распланировать, и понятны связанные с ним риски. + +Невозможно выполнить туманные требования вроде "Построить систему, которая будет вычислять самую привлекательную прическу и цвет волос для каждого клиента". Если требование можно сделать более четким, оно зачастую станет сложнее, например, "Построить систему, которая будет вычислять самую привлекательную прическу и цвет для клиента, позволять им предварительно просматривать решение, изменять его и настолько хорошо удовлетворять клиента, что мы будем получать от этого кучу денег". Если нет четкого определения успеха, то вы не добьетесь его. + +Следующее: [Как использовать встроенные языки](02-How-to-Utilize-Embedded-Languages.md) diff --git a/ru/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md b/ru/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md new file mode 100644 index 0000000..e1e43ab --- /dev/null +++ b/ru/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -0,0 +1,11 @@ +# Как использовать встроенные языки + +Встраивание языка программирования в систему обладает почти эротическим притяжением для программиста. Это одно из самых творческих свершений, которые он может сделать. Встроенный язык делает систему невероятно мощной и позволит вам использовать ее самые творческие возможности. Это превратит систему в вашего друга. + +У лучших тестовых редакторов есть встроенные языки программирования. Это можно использовать в той мере, в какой целевая аудитория может овладеть этими языками. Конечно, можно сделать использование встроенного языка необязательным, как это и делается в текстовых редакторах, так что ими пользуются опытные пользователи, а остальным они и не нужны. + +Я и многие другие программисты попадали в ловушку создания встроенных языков со специальным назначением. Я попадался на это дважды. В мире уже существует множество языков, которые спроектированы специально для подобных целей. Подумайте дважды, прежде чем создавать еще один. + +Вопрос, который стоит задать себе перед встраиванием языка, звучит так: входит ли использование таких языков в культуру моих пользователей или нет? Если ваша целевая аудитория состоит исключительно из непрограммистов, то насколько поможет внедрение языка в систему? Если целевая аудитория состоит из программистов, то не предпочтут ли они API? И какой язык вы собираетесь встраивать? Программисты не очень любят изучать новый язык, если у него узкое применение. Но если он похож на то, с чем они уже работают, то они быстро освоят его. Создавать новый язык - это огромное удовольствие и радость. Но мы не должны позволять этой радости ослеплять нас и затмевать потребности пользователя. Если только у вас не по-настоящему оригинальные запросы и идеи, то почему бы не использовать уже существующий язык, с которым знакома некоторая часть ваших пользователей? + +Следующее: [Выбор языка программирования](03-Choosing-Languages.md) diff --git a/ru/3-Advanced/Technical-Judgment/03-Choosing-Languages.md b/ru/3-Advanced/Technical-Judgment/03-Choosing-Languages.md new file mode 100644 index 0000000..6ea9c91 --- /dev/null +++ b/ru/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -0,0 +1,15 @@ +# Выбор языка программирования + +Программист-одиночка, любящий свою работу, может позволить себе выбирать язык, который лучше всего подходит для задачи. Но у большинства работающих программистов небольшой выбор языка, с которым они работают. Обычно за них это решают руководители, которые больше принимают политическое, а не технологическое решение. Часто руководителям не хватает смелости использовать нетрадиционный инструмент, даже если они знают, иногда по собственному опыту, что менее распространенный инструмент лучше. В других случаях преимущество того, что большая часть команды и иногда более широкого общества владеет инструментом, делает невозможным выбор иного языка со стороны отдельного программиста. Часто менеджеры руководствуются необходимостью нанимать программистов с опытом с определенным языком. Вне сомнений они делают то, что считают лучшим для компании или проекта, и их стоит уважать за это. Однако, я лично считает этот подход одним из самых бесполезных и ошибочных, которые можно только встретить. + +Но конечно, все не так однозначно. Даже если основной язык обязателен, и вы не можете изменить его, часто случается, что некоторые инструменты или сторонние программы можно и нужно написать на других языках. Если язык должен быть встроен в систему (и вам всегда следует рассмотреть такую возможность), то его выбор во многом будет зависеть от пользователей системы. Из таких случаев следует извлекать выгоду и выбирать лучший язык для компании или проекта. Заодно это делает работу намного интереснее. + +Языки программирования в действительности стоит называть нотациями, поскольку выучить один из них не так трудно, как естественный язык. Для начинающих или непосвященных "выучить новый язык программирования" кажется сложной задачей, но после трех языков это всего лишь вопрос знакомства с доступными библиотеками. Некоторые склонны думать о большой системе, в которой компоненты написаны на трех-четырех языках, как о беспорядочной солянке, но я утверждаю, что такая система во многих случаях превосходит систему, написанную на одном языке: + +- Между компонентами, написанными на разных языках, нет тесной связи, они лучше изолированы друг от друга (хотя они могут иметь не совсем понятные интерфейсы) +- Вы можете легко внедрить новый язык или платформу, переписав индивидуально по очереди каждый компонент +- Один язык может не подходить для всех задач системы. Имея несколько языков для компонентов, вы можете выбирать наиболее подходящий для конкретной задачи + +Некоторые из этих преимуществ чисто психологические, но психология тоже важна. В конце концов, издержки языковой тирании перевешивают любые преимущества, которые она дает. + +Следующее: [Правильные компромиссы. Как справляться с давлением графика](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/ru/5-Bibliography.md b/ru/5-Bibliography.md new file mode 100644 index 0000000..8274f28 --- /dev/null +++ b/ru/5-Bibliography.md @@ -0,0 +1,31 @@ +# Приложение A - Библиография/Список сайтов +[//]: # (Version:1.0.0) +## Книги + +[Rules00] Guy Kawasaki, Michelle Moreno, and Gary Kawasaki. 2000. HarperBusiness. Rules for Revolutionaries: The Capitalist Manifesto for Creating and Marketing New Products and Services. + +[RDev96] Steve McConnell. 1996. Microsoft Press. Redmond, Wash. Rapid Development: Taming Wild Software Schedules. + +[CodeC93] Steve McConnell. 1993. Microsoft Press. Redmond, Wash. Code Complete. + +[XP99] Kent Beck. 1999. 0201616416. Addison-Wesley. Extreme Programming Explained: Embrace Change. + +[PlanXP00] Kent Beck and Martin Fowler. 2000. 0201710919. Addison-Wesley. Planning Extreme Programming. + +[Prag99] Andrew Hunt, David Thomas, and Ward Cunningham. 1999. 020161622X. Addison-Wesley. The Pragmatic Programmer: From Journeyman to Master. + +[Stronger] Friedrich Nietzsche. 1889. Twilight of the Idols, "Maxims and Arrows", section 8. + +## Сайты + +[PGSite] Пол Грэхем. 2002. Статьи на его вебсайте: [http://www.paulgraham.com/articles.html](http://www.paulgraham.com/articles.html). Рекомендую все статьи, особенно "Beating the Averages". + +[Hacker] Эрик С. Рэймонд. 2003. How to Become a Hacker. [http://www.catb.org/~esr/faqs/hacker-howto.html](http://www.catb.org/~esr/faqs/hacker-howto.html). + +[HackDict] Эрик С. Рэймонд. 2003. The New Hacker Dictionary. [http://catb.org/esr/jargon/jargon.html](http://catb.org/esr/jargon/jargon.html). + +[ExpCS] Эдсгер В. Дейкстра. 1986. How Experimental is Computing Science?. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF). + +[Knife] Эдсгер В. Дейкстра. 1984. On a Cultural Gap. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF). + +Следующее: [История](6-History.md) \ No newline at end of file diff --git a/ru/6-History.md b/ru/6-History.md new file mode 100644 index 0000000..59676e1 --- /dev/null +++ b/ru/6-History.md @@ -0,0 +1,43 @@ +# Приложение B - История +[//]: # (Version:1.0.0) +## Переезд на Github + +Это эссе было перемещено в репозиторий Gihub для более простого распространения, обновлени и улучшения. Оно было скопировано [Брейди Гроувом](https://github.com/braydie) с [http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm). Эссе переехало на Github в январе 2016 года. + +## Просьба об обратной связи и дополнениях + +Пожалуйста, присылайте любые комментарии, которые у вас есть по этому эссе. Я рассматриваю все предложения, многие из них уже внесли свой вклад в улучшение эссе. + +Я разместил эссе под GNU Free Documentation License. Эта лицензия не предназначена специально для эссе. Они обычно представляют собой последовательные и убедительные тезисы, изложенные с одной точки зрения в едином стиле. Я надеюсь, что это эссе будет коротким и приятным чтением. + +Я также надеюсь, что оно поучительным. Хоть это и не учебник, я разбил его на множество маленьких разделов, к которым можно легко добавлять новые. Если у вас есть желание, вы можете расширить это эссе по своему усмотрению в соответствии с положениеями лицензии. + +Возможно, самонадеянно полагать, что документ достоин расширения, но надежда вечна. Я был бы счастлив, если бы он был бы расширен следующим образом: + +- Добавление полного списка литературы к каждому разделу +- Добавление новых и лучших разделов +- Переводы на другие языки, даже если только на основе подразделов +- Критика или построчные комментарии +- Возможность преобразовывать в другие форматы, такие как PALM и более совершенный HTML + +Если вы сообщите мне о своей работе, я рассмотрю ее и, возможно, включу в последующие версии в соответствии с положениями лицензии. Конечно, вы можете создать свою собственную версию этого документа без моего ведома, как это разъясняется в лицензии. + +Спасибо. + +Роберт Л. Рид + +## Оригинальная версия + +Оригинальная версия этого документа была начата Робертом Л. Ридом в 2000 году и впервые опубликована в электронном вида в Samizdat Press(http://Samizdat.mines.edu) в 2002 году. Он посвящен программистам Hire.com. + +После того, как статья была упомянута на Slashdot в 2003 году, около 75 человек прислали мне письма с предложениями и найденными ошибками. Я ценю помощь и вклад каждого из них. Было немало повторов, но эти люди внесли значимые предложения или первые заметили ошибки, которые я позже исправил: Морган МакГуайр, Дэвид Мейсон, Том Мортел, Ninja Programmer на Slashdot, Бен Верк, Роб Хаферник, Марк Хоув, Питер Парейт, Брайан Грейсон, Зед А. Шоу, Стив, Бенц, Максим Йоффе, Эндрю Ву, Дэвид Джецке и Том Коркоран. + +Наконец, я хотел бы поблагодарить Кристину Валлери, чья редакция и вычитка существенно улучшили второй черновик, и Уэйна Аллена, который побудил мне начать это эссе. + +## Биография автора + +Роберт Л. Рид живет в Остине, Техас, с женой и двумя детьми. В настоящее время он работает главным инженером в Hire.com, где он работает последние четыре года. До этого он основал 4R Technology, разработавшую инструмент контроля качества для анализа изображений на основе сканнера в индустрии производства бумаги. + +Роберт получил ученую степень PhD в университете Техаса в Остине в 1995 году в области информатики, связанной с теорией баз данных. В 1987 году он получил степень бакалавра информатики в университете Райса. Он работает программистом с 16 лет. + +Следующее: [Лицензия](LICENSE.md) diff --git a/ru/7-Contributions.md b/ru/7-Contributions.md new file mode 100644 index 0000000..db78808 --- /dev/null +++ b/ru/7-Contributions.md @@ -0,0 +1,32 @@ +# Участие в проекте +[//]: # (Version:1.0.0) +Данный репозиторий предназначен для проекта с участием широкого общества. Ваш личный вклад существенно улучшит качества данного эссе. + +## Как я могу внести свой вклад в проект? +Есть несколько способов внести свой вклад в проект. + +- Идеи по новым разделам +- Улучшения уже имеющихся разделов +- Выявление опечаток или иных ошибок в разделах +- Добавление новых ссылок на источники в разделах +- Общие предложения по улучшению проекта +- Переводы на другие языки + +## Переводы + +В настоящее время это эссе переведено с английского на следующие языки: + +- Китайский. Переводчик [ahangchen](https://github.com/ahangchen) +- Русский. Переводчик [paveltovchigrechko](https://github.com/paveltovchigrechko) + +**Если вы предоставляете начальный перевод эссе на другой язык, то вы получаете право стать соавтором проекта для поддержки и ревью изменений в вашем переводе.** + +## Участники проекта + +Github содержит список всех [участников](https://github.com/braydie/HowToBeAProgrammer/graphs/contributors) данного проекта. + +## Редакция и переезд на Github + +[Braydie Grove](https://www.github.com/braydie) согласился быть главным редактором проекта. + +Он перевел оригинальное эссе в MarkDown и создал данный репозиторий. diff --git a/ru/GLOSSARY.md b/ru/GLOSSARY.md new file mode 100644 index 0000000..a8a956f --- /dev/null +++ b/ru/GLOSSARY.md @@ -0,0 +1,75 @@ +# Глоссарий +[//]: # (Version:1.0.0) +В данном глоссарии собраны термирны, использующиеся в эссе. Термины необязательно имеют стандартное для большинства людей значение. Эрик С. Рэймонд собрал массивный и информативный глоссарий[HackerDict], оценив малую часть которого, можно с удовольствием прочесть от корки до корки, как бы это странно ни звучало. + +### Вывод в консоль + +Вставка в программу временных команд, которые выводят информацию о ее выполнении для последующей отладки. + +### Логирование + +Практика писать программу таким образом, чтобы она могла выводить настраиваемый отчет, описывающий ход ее исполнения. + +### Босс + +Человек, который назначает вам задачи. В некоторых случаях, это сам пользователь. + +### Клан + +Люди, которые разделяют с вами верность некой общей цели или профессии. + +### Бизнес + +Группа людей, организованных для получения прибыли. + +### Компания + +Группа людей, организованных для получения прибыли. + +### Слепота прокрутки + +Невозможность найти нужную информацию из-за того, что она спрятана в большом количестве другой, менее интересной, информации. + +### Реальное время + +Фактическое время исполнения программы, измеряемое настенными часами, противоположность процессорного времени. + +### Узкое место + +Главное ограничение в производительности системы. Ограничение, которые снижает производительность. + +### Выделенная куча + +Память можно назвать "выделенной в куче", когда механизм по ее освобождению можно назвать сложным. + +### Мусор + +Память, которую занимают ненужные более для приложения объекты. + +### Сборщик мусора + +Система для обработки мусора. + +### Утечка памяти + +Набор нежелаемых ссылок на объекты, которые мешают сборке мусора. Либо ошибка в сборщике мусоре или системе управления памяти. Приводит к постепенному увеличению памяти, которую запрашивает программа с течением времени. + +### Экстремальное программирование + +Стиль разработки, которые акцентируется на общении с клиентами и автоматизированным тестированием. + +### Спекулятивное программирование + +Создание функции до того, как точно определено, будет ли она полезна. + +### Объектно-ориентированное программирование + +Стиль программирования, акцентирующийся на управлении внутренним состоянием объектов. + +### Языки взаимодействия систем + +Язык, спроектированный в первую очередь для стандартизации, чем для непосредственного использования. + +### Программная нотация + +Синоним для термина "языка программирования", который почеркивает математическую природу языков программирования и их простоту относительно естественных языков. diff --git a/ru/LICENSE.md b/ru/LICENSE.md new file mode 100644 index 0000000..7c36621 --- /dev/null +++ b/ru/LICENSE.md @@ -0,0 +1,11 @@ + +## Creative Commons Attribution Share-Alike + +"Как быть программистом: Community Version", авторы Robert L. Read и Community, издано под лицензией Creative Commons Attribution Share-Alike Internal v 4.0. + +В настоящее время данная работа находится под редакцией Брейди Гроува и Роберта Л. Рида. + +Мы поддерживаем разумные попытки поддержать вклад со стороны общества, так как это описано в разделе "Участие в проекте". Если вы создаете пулл-реквест со значительными изменениями, пожалуйста, добавьте краткое описание вашего вклада в данной секции. + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/ru/README.md b/ru/README.md new file mode 100644 index 0000000..d6ae0df --- /dev/null +++ b/ru/README.md @@ -0,0 +1,103 @@ +# Как быть программистом: Community Version +[//]: # (Version:1.0.0) +Robert L. Read with Community + +Copyright 2002, 2003, 2016 Robert L. Read + +Выпущено под лицензией [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +## Введение +Быть хорошим программистом трудно и благородно. Самое сложное в коллективной разработке программного обеспечения это взаимодействие с коллегами и клиентами. Писать компьютерные программы важно и требует многих знаний и навыков, но это лишь детский лепет по сравнению с тем прочим, что хороший программист должен делать, чтобы создать программное обеспечение, успешное как для клиентов, так для множества коллег, за которых он несет частичную ответственность. В данном эссе я попытаюсь как можно более кратко изложить все те нюансы и детали, которые я сам бы хотел, чтобы кто-нибудь мне объяснил, когда мне был двадцать один год. + +Это очень субъективная тема, поэтому данное эссе неизбежно будет отражать мои личные взгляды и убеждения. Я ограничу себя проблемами, с которыми, скорее всего, столкнется почти каждый программист во время работы. Многие из них, а также их решения являются настолько общечеловеческими, что вероятно, мой тон покажется назидательным. Несмотря на это, я надеюсь, что эссе окажется полезным. + +Программирование преподается на курсах. Великолепные книги The Pragmatic Programmer [Prag99], Code Complete [CodeC93], Rapid Development [RDev96] и Extreme Programming Explained [XP99]: все обучают программированию и более общим вопросам о том, как быть хорошим программистом. До или вместе с данной статьей непременно стоит ознакомиться также с эссе Пола Грехэма [PGSite] и Эрика Рэймонда [Hacker]. Данное эссе слегка отличается от этих великолепных работ тем, что акцентирует внимание на социальных проблемах и обобщает набор навыков, необходимых программисту, с моей личной точки зрения. + +В данном эссе я называю "боссом" любого, кто ставит перед вами задачи. Слова "бизнес", "компания" и "клан" я использую как синонимы, кроме тех случаев, когда "бизнес" означает генерирование прибыли, "компания" - место работы, а "клан" - людей, с которыми вы разделяете преданность общему делу или профессии. + +Добро пожаловать в клан. + +## Содержание + +1. [Начинающий программист](1-Beginner) + - Личные навыки + - [Научитесь отлаживать](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [Как отлаживать, разделяя пространство проблемы](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [Как устранять баги](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [Как отлаживать, используя логи](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [Как определять проблемы производительности](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [Как устранять проблемы производительности](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [Как оптимизировать циклы](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [Как справиться с расходами на операции чтения и записи](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [Как управлять памятью](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [Как устранять плавающие баги](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [Как научиться проектировать программы](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [Как экспериментировать](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - Командные навыки + - [Почему важно оценивать задачи](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [Как оценивать время на разработку](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [Как искать информацию](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [Как спрашивать людей](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [Как документировать правильно](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [Как работать с плохим кодом](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [Как использовать системы контроля версий](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [Как писать юнит-тесты](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [Делайте перерывы, когда вы в тупике](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [Как понять, когда идти домой](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [Как вести себя с трудными людьми](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [Программист среднего уровня](2-Intermediate) + - Личные навыки + - [Как сохранять мотивацию](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [Как заслужить доверие](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [Как балансировать процессорное время и память](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [Как проводить стресс-тестирование](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [Как балансировать краткость и абстракцию](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [Как осваивать новые навыки](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [Научитесь печатать вслепую](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [Как проводить интеграционное тестирование](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [Языки взаимодействия систем](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [Стандартные технологии](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [Как анализировать данные](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - Командные навыки + - [Как управлять временем разработки](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [Как управлять рисками, связанными со сторонним программным обеспечением](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [Как руководить консультантами](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [Как соизмерять количество общения](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [Как честно выражать несогласие](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - Экспертиза + - [Как балансировать качество и время разработки](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [Как управлять зависимостями](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [Как оценивать стороннее программное обеспечение](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [Как решить: покупать программу или писать свою](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [Как расти профессионально](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [Как проводить собеседования](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [Как понять, когда применять высокие технологии](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [Как разговаривать с неинженерами](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [Продвинутый программист](3-Advanced) + - Техническая экспертиза + - [Как отличить сложное от невозможного](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [Как использовать встроенные языки](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [Выбор языка программирования](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - Правильные компромиссы + - [Как справляться с давлением графика](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [Как понять пользователя](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [Как получить повышение](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - Управление командой + - [Как развивать таланты](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [Как выбрать, над чем работать](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [Как получить наибольшую отдачу от коллег](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [Как разделять задачи](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [Как распределять скучные задания](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [Как получить поддержку для проекта](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [Как развивать систему](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [Как качественно взаимодействовать](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [Как сообщать неприятное](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [Как справляться с менеджерскими мифами](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [Как справляться с организационным хаосом](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [Глоссарий](GLOSSARY.md) +5. [Приложение A - Библиография/Список сайтов](5-Bibliography.md) +6. [Приложение B - История (на январь 2016)](6-History.md) +7. [Приложение C - Участие в проекте (на январь 2016)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/ru/SUMMARY.md b/ru/SUMMARY.md new file mode 100644 index 0000000..4f01b51 --- /dev/null +++ b/ru/SUMMARY.md @@ -0,0 +1,81 @@ +# Содержание +[//]: # (Version:1.0.0) +* [Начинающий программист](1-Beginner/README.md) + * Личные навыки + * [Научитесь отлаживать](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + * [Как отлаживать, разделяя пространство проблемы](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + * [Как устранять баги](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + * [Как отлаживать, используя логи](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + * [Как определять проблемы производительности](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + * [Как устранять проблемы производительности](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + * [Как оптимизировать циклы](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + * [Как справиться с расходами на операции чтения и записи](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + * [Как управлять памятью](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + * [Как устранять плавающие баги](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + * [Как научиться проектировать программы](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + * [Как экспериментировать](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + * Командные навыки + * [Почему важно оценивать задачи](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + * [Как оценивать время на разработку](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + * [Как искать информацию](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + * [Как спрашивать людей](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + * [Как документировать правильно](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + * [Как работать с плохим кодом](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + * [Как использовать системы контроля версий](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + * [Как писать юнит-тесты](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + * [Делайте перерывы, когда вы в тупике](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + * [Как понять, когда идти домой](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + * [Как вести себя с трудными людьми](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +* [Программист среднего уровня](2-Intermediate/README.md) + * Личные навыки + * [Как сохранять мотивацию](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + * [Как заслужить доверие](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + * [Как балансировать процессорное время и память](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + * [Как проводить стресс-тестирование](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + * [Как балансировать краткость и абстракцию](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + * [Как осваивать новые навыки](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + * [Научитесь печатать вслепую](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + * [Как проводить интеграционное тестирование](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + * [Языки взаимодействия систем](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + * [Стандартные технологии](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + * [Как анализировать данные](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + * Командные навыки + * [Как управлять временем разработки](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + * [Как управлять рисками, связанными со сторонним программным обеспечением](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + * [Как руководить консультантами](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + * [Как соизмерять количество общения](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + * [Как честно выражать несогласие](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + * Экспертиза + * [Как балансировать качество и время разработки](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + * [Как управлять зависимостями](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + * [Как оценивать стороннее программное обеспечение](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + * [Как решить: покупать программу или писать свою](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + * [Как расти профессионально](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + * [Как проводить собеседования](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + * [Как понять, когда применять высокие технологии](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + * [Как разговаривать с неинженерами](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +* [Продвинутый программист](3-Advanced/README.md) + * Техническая экспертиза + * [Как отличить сложное от невозможного](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + * [Как использовать встроенные языки](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + * [Выбор языка программирования](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + * Правильные компромиссы + * [Как справляться с давлением графика](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + * [Как понять пользователя](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + * [Как получить повышение](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + * Управление командой + * [Как развивать таланты](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + * [Как выбрать, над чем работать](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + * [Как получить наибольшую отдачу от коллег](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + * [Как разделять задачи](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + * [Как распределять скучные задания](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + * [Как получить поддержку для проекта](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + * [Как развивать систему](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + * [Как качественно взаимодействовать](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + * [Как сообщать неприятное](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + * [Как справляться с менеджерскими мифами](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + * [Как справляться с организационным хаосом](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +* [Глоссарий](GLOSSARY.md) +* [Приложение A - Библиография/Список сайтов](5-Bibliography.md) +* [Приложение B - История (на январь 2016)](6-History.md) +* [Приложение C - Участие в проекте (на январь 2016)](7-Contributions.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/01-Learn-To-Debug.md b/zh-traditional/1-Beginner/Personal-Skills/01-Learn-To-Debug.md new file mode 100644 index 0000000..7a87592 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -0,0 +1,21 @@ +# 學習除錯 + + +[//]: # (Version:1.0.0) +除錯是成為程式設計師的基石。除錯這個詞第一個含義是移除錯誤,但真正有意義的含義是透過檢查來觀察程式的運行。一個不會除錯的程式設計師等同於盲人。 + +理想主義者認為設計、分析、複雜的理論或其他東西比實際除錯更基本,他們不是現實的程式設計師。現實的程式設計師不會活在理想的世界裡。即使你是完美的,你也需要與你周圍主要的軟體公司或組織的程式碼,和你同事寫的程式碼打交道。這些程式碼和它們的文件大多數都是不完美的。如果不能洞察程式碼的具體執行過程,最小的変動都會把你永遠地拋出去。通常這種可見性只能從實驗獲得,也就是除錯。 + +除錯是與程式運行相關的事情,而非與程式本身相關。你從主要的軟體公司購買一些產品,通常不會看到產品背後的程式碼。但程式碼不遵循文件的情況或文件沒有說明的情況仍然會出現。更常見的是,你的程式出現了一個錯誤,當你檢查你寫的程式碼的時候,卻不知道這個錯誤是怎麼發生的。這意味著你做的一些假設並不對,或者一些你沒有預料到的情況發生了。有時候,奇妙的修改程式碼的技巧可能會生效。當無效時,你必須除錯。 + +為了獲得程式執行過程的可見性,你必須能夠執行程式碼並從這個過程中觀察到發生了什麼。有時候這是顯而易見的,比如一些正在呈現在螢幕上的東西,或者兩個事件之間的延遲。在許多其他的案例中,除錯與一些不一定可見的東西相關,比如程式碼中一些變量的狀態,哪一行程式碼正在被執行,或者一些斷言是否持有了一個複雜的資料結構。這些隱藏的細節必須被顯露出來。 + +觀察一個正在執行程式的內部的方法通常可按如下分類: + +- 使用一個除錯工具; +- Logging [(詳情看)](../../4-Glossary.md) - 利用打印程式句子顯示變數值,找出流程出錯地方。 + +當除錯工具穩定可用時,它們是非常美妙的,但 Printlining 和寫日志甚至是更加重要的。除錯工具通常落後於編程語言的發展,所以在某些時候它們都可能是無效的。另外,除錯工具可能輕微改變程式實際執行的方式。最后,除錯有許多種,比如檢查一個斷言和一個巨大的資料結構,這需要寫程式碼並改變程式的運行。當除錯工具可用時,知道如何使用除錯工具是一件好事,但學會使用其他兩種方式也是至關重要的。 + +當除錯需要修改程式碼的時候,一些初學者會感到害怕。這是可以理解的,這有點像探索性外科手術。但你需要學會打破程式碼,讓它跳起來,你需要學會在它上面做實驗,並需要知道你臨時對它做的任何事情都不會使它變得更糟。如果你感受到了這份恐懼,找一位導師 - 正是因為許多人在一開始面對這種恐懼的時候表現的太脆弱,我們因此失去了很多本可以變成優秀程式設計師的人。 +Next [如何通过分离问题空间来 Debug](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md b/zh-traditional/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md new file mode 100644 index 0000000..fd1da41 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -0,0 +1,15 @@ +# 如何通过分割问题 Debug +[//]: # (Version:1.0.0) +调试是有趣的,因为它一开始是个迷。你认为它应该这样做,但实际上它却那样做。很多时候并不仅是这么简单---我给出的任何例子都会被设计来与一些偶尔在现实中会发生的情况相比较。调试需要创造力与智谋。如果说调试有简单之道,那就是在这个谜题上使用分治法。 + +假如,你创建了一个程序,它会依次执行十件事情。当你运行它的时候,它却崩溃了。但你本来的目的并不是想让它崩溃,所以现在一个谜题扔给你了。当你查看输出时,你可以看到序列里前七件事情运行成功了。最后三件事情在输出里却看不到,所以你的谜题变小了:“它是在执行第8、9、10件事的时候崩溃的”。 + +你是否可以设计一个实验来观察它是在哪件事情上崩溃呢?当然,你可以用一个调试器或者我们可以在第8第9件事后面加一些[printlining](../../4-Glossary.md)的语句(或者你正在使用的任何语言里的等价的事情),当我们重新运行它的时候,我们的谜题会变得更小,比如“它是在做第九件事的时候崩溃的”。我发现,把谜题是怎样的一直清楚地记在心里能让我们保持注意力。当几个人在一个问题的压力下一起工作时,很容易忘记最重要的谜题是什么。 + +调试技术中分治的关键和算法设计里的分治是一样的。你只要从中间开始划分,就不用划分太多次,并且能快速地调试。但问题的中点在哪里?这就是真正需要创造力和经验的地方了。 + +对于一个真正的初学者来说,可能发生错误的地方好像在代码的每一行里都有。一开始,你看不到一些你稍后开发的时候才会看到的其它纬度,比如执行过的代码段,数据结构,内存管理,与外部代码的交互,一些有风险的代码,一些简单的代码。对于一个有经验的程序员,这些其他的维度为整个可能出错的事情展示了一个不完美但是有用的思维模型。拥有这样的思维模型能让一个人更高效地找到谜题的中点。 + +一旦你最终划分出了所有可能出错的地方,你必须试着判断错误躲在哪个地方。比如:这样一个谜题,哪一行未知的代码让我的程序崩溃了?你可以这样问自己,出错的代码是在我刚才执行的程序中间的那行代码的前面还是后面?通常你不会那么幸运就能知道错误在哪行代码甚至是哪个代码块。通常谜题更像这个样子的:“图中的一个指针指向了错误的结点还是我的算法里变量自增的代码没有生效?”,在这种情况下你需要写一个小程序去确认图中的指针是否都是对的,来决定分治后的哪个部分可以被排除。 + +Next [如何移除错误](03-How-to-Remove-an-Error.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md b/zh-traditional/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md new file mode 100644 index 0000000..34a55c8 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -0,0 +1,9 @@ +# 如何移除一个错误 +[//]: # (Version:1.0.0) +我曾有意把检查程序执行和修复错误分割开来,但是当然,调试也意味着移除 bug。理想状况下,当你完美的发现了错误以及它的修复方法时,你会对代码有完美的理解,并且有一种顿悟(啊哈!)的感觉。但由于你的程序会经常使用其他不具有可视性的、没有一致性注释的系统(比如第三方库),所以完美是不可能的。在其他情况下,可能代码是如此的复杂以至于你的理解可能并不完美。 + +在修复 bug 时,你可能想要做最小的改变来修复它。你可能看到一些其他需要改进的东西,但不会同时去改进他们。请使用科学的方法去改进一个东西,并且一次只改变一个东西。修复 bug 最好的方式是能够重现 bug,然后把你的修复替换进去,重新运行你的程序,观察,直到 bug 不再出现。当然,有时候不止一行代码需要修改,但你在逻辑上仍然需要使用一个独立原子(译者注:以前人们认为原子不可再分,所以用用原子来代表不可再分的东西)的改变来修复这个 bug。 + +有时候,可能实际上有几个 bug,但表现出来好像是一个。这取决于你怎么定义 bug,你需要一个一个地修复它们。有时候,程序应该做什么或者原始作者想要做什么是不清晰的。在这种情况下,你必须多加练习,增加经验,评判并为代码赋予你自己的认知。决定它应该做什么,并注释或用其他方式阐述清楚,然后修改代码以遵循你赋予的含义。这是一个进阶或高级的技能,有时甚至比一开始用原始的方式创建这些代码还难,但真实的世界经常是混乱的。你必须修复一个你不能重写的系统。 + +Next [如何使用日志调试](04-How-to-Debug-Using-a-Log.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md b/zh-traditional/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md new file mode 100644 index 0000000..ac1dddc --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -0,0 +1,13 @@ +# 如何使用日志调试 +[//]: # (Version:1.0.0) +*Logging*(日志)是一种编写系统的方式,可以产生一系列信息记录,被称为 log。*Printlining* 只是输出简单的,通常是临时的日志。初学者一定要理解并且使用日志,因为他们对编程的理解是局限的。因为系统的复杂性,系统架构必须理解与使用日志。在理想的状态下,程序运行时产生的日志信息数量需要是可配置的。通常,日志提供了下面三个基本的优点: + +- 日志可以提供一些难以重现的 bug 的有效信息,比如在产品环境中发生的、不能在测试环境重现的 bug。 +- 日志可以提供统计和与性能相关的数据,比如语句间流逝过的时间。 +- 可配置的情况下,日志允许我们获取普通的信息,使得我们可以在不修改或重新部署代码的情况下调试以处理具体的问题。 + +需要输出的日志数量总是一个简约与信息量的权衡。太多的信息会使得日志变得昂贵,并且造成[*滚动目盲*](../../4-Glossary.md),使得发现你想要的信息变得很困难。但信息太少的话,日志可能不包含你需要的信息。出于这个原因,让日志的输出可配置是非常有用的。通常,日志中的每个记录会标记它在源代码里的位置,执行它的线程(如果可用的话),时间精度,并且通常还有一些额外的有效信息,比如一些变量的值,剩余内存大小,数据对象的数量,等等。这些日志语句撒遍源码,但只出现在主要的功能点和一些可能出现危机的代码里。每个语句可以被赋予一个等级,并且只有在系统被配置成输出相应等级的记录的时候才输出这个等级的记录。你应该设计好日志语句来标记你预期的问题。预估测量程序表现的必要性。 + +如果你有一个永久的日志,printling 现在可以用日志的形式来完成,并且一些调试语句可能会永久地加入日志系统。 + +Next [如何理解性能问题](05-How-to-Understand-Performance-Problems.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md b/zh-traditional/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md new file mode 100644 index 0000000..8c0bf70 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -0,0 +1,11 @@ +# 如何理解性能问题 +[//]: # (Version:1.0.0) +学习理解运行的程序的性能问题与学习 debug 是一样不可避免的。即使你完美、精确地理解了你的代码运行时所产生的开销,你的代码也会调用其他你几乎不能控制的或者几乎不可看透的软件系统。然而,实际上,通常性能问题和调试有点不一样,而且往往要更简单些。 + +假如你或你的客户认为你的一个系统或子系统运行太慢了。在你把它变快之前,你必须构建一个它为什么慢的思维模型。为了做到这个,你可以使用一个图表工具或者一个好的日志,去发现时间或资源真正被花费在什么地方。有一句很有名的格言:90%的时间会花费在10%的代码上。在性能这个话题上,我想补充的是输入输出开销的重要性。通常大部分时间是以某种形式花费在 I/O 上。发现昂贵的 I/O 和昂贵的10%代码是构建思维模型的一个好的开始。 + +计算机系统的性能有很多个维度,很多资源会被消耗。第一种资源是“挂钟时间”,即执行程序的所有时间。记录“挂钟时间”是一件特别有价值的事情,因为它可以告诉我们一些图表工具表现不了的不可预知的情况。然而,这并不总是描绘了整幅图景。有时候有些东西只是稍微多花费了一点点时间,并且不会引爆什么问题,所以在你真实要处理的计算机环境中,多一些处理器时间可能会是更好的选择。相似的,内存,网络带宽,数据库或其他服务器访问,可能最后都比处理器时间要更加昂贵。 + +竞争共享的资源被同步使用,可能导致死锁和互斥。死锁是由于不恰当的同步和请求资源导致线程执行能力的丧失。互斥是对于资源访问的不恰当安排。如果这是可以预料到的,最好在你的项目开始前就采取措施来地衡量线程争抢。即使线程争抢不会发生,对于有效维护它们也是很有帮助的。 + +Next [如何修复性能问题](06-How-to-Fix-Performance-Problems.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md b/zh-traditional/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md new file mode 100644 index 0000000..69e3f37 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -0,0 +1,13 @@ +# 如何修复性能问题 +[//]: # (Version:1.0.0) +大部分软件都可以通过付出相对较小的努力,让他们比刚发布时快上10到100倍。在市场的压力下,选择一个简单而快速的解决问题的方法是比选择其它方法更为明智而有效率的选择。然而,性能是可用性的一部分,而且通常它也需要被更仔细地考虑。 + +提高一个非常复杂的系统的性能的关键是,充分分析它,来发现其“瓶颈”,或者其资源耗费的地方。优化一个只占用1%执行时间的函数是没有多大意义的。一个简要的原则是,你在做任何事情之前必须仔细思考,除非你认为它能够使系统或者它的一个重要部分至少快两倍。通常会有一种方法来达到这个效果。考虑你的修改会带来的测试以及质量保证的工作需要。每个修改带来一个测试负担,所以最好这个修改能带来一点大的优化。 + +当你在某个方面做了一个两倍提升后,你需要至少重新考虑并且可能重新分析,去发现系统中下一个最昂贵的瓶颈,并且攻破那个瓶颈,得到下一个两倍提升。 + +通常,性能的瓶颈的一个例子是,数牛的数目:通过数脚的数量然后除以4,还是数头的数量。举些例子,我曾犯过的一些错误:没能在关系数据库中,为我经常查询的那一列提供适当的索引,这可能会使得它至少慢了20倍。其他例子还包括在循环里做不必要的 I/O 操作,留下不再需要的调试语句,不再需要的内存分配,还有,尤其是,不专业地使用库和其他的没有为性能充分编写过的子系统。这种提升有时候被叫做“低垂的水果”,意思是它可以被轻易地获取,然后产生巨大的好处。 + +你在用完这些“低垂的水果”之后,应该做些什么呢?你可以爬高一点,或者把树锯倒。你可以继续做小的改进或者你可以严肃地重构整个系统或者一个子系统。(不只是在新的设计里,在信任你的 boss 这方面,作为一个好的程序员,这是一个非常好的使用你的技能的机会)然而,在你考虑重构子系统之前,你应该问你自己,你的建议是否会让它好五倍到十倍。 + +Next [如何优化循环](07-How-to-Optimize-Loops.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md b/zh-traditional/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md new file mode 100644 index 0000000..4059d6d --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -0,0 +1,15 @@ +# 如何优化循环 +[//]: # (Version:1.0.0) +有时候你会遇到循环,或者递归函数,它们会花费很长的执行时间,可能是你的产品的瓶颈。在你尝试使循环变得快一点之前,花几分钟考虑是否有可能把它整个移除掉,有没有一个不同的算法?你可以在计算时做一些其他的事情吗?如果你不能找到一个方法去绕开它,你可以优化这个循环了。这是很简单的,move stuff out。最后,这不仅需要智慧而且需要理解每一种语句和表达式的开销。这里是一些建议: + +- 删除浮点运算操作。 +- 非必要时不要分配新的内存。 +- 把常量都放在一起声明。 +- 把 I/O 放在缓冲里做。 +- 尽量不使用除法。 +- 尽量不适用昂贵的类型转换。 +- 移动指针而非重新计算索引。 + +这些操作的具体代价取决于你的具体系统。在一些系统中,编译器和硬件会为你做一些事情。但必须清楚,有效的代码比需要在特殊平台下理解的代码要好。 + +Next [如何处理I/O开销](08-How-to-Deal-with-IO-Expense.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md b/zh-traditional/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md new file mode 100644 index 0000000..1c3e712 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -0,0 +1,13 @@ +# 如何处理I/O代价 +[//]: # (Version:1.0.0) +在很多问题上,处理器的速度比硬件交流要快得多。这种代价通常是小的 I/O,可能包括网络消耗,磁盘 I/O,数据库查询,文件 I/O,还有其他与处理器不太接近的硬件使用。所以构建一个快速的系统通常是一个提高 I/O,而非在紧凑的循环里优化代码或者甚至优化算法的问题。 + +有两种基本的技术来优化 I/O:缓存和代表(译者注:比如用短的字符代表长的字符)。缓存是通过本地存储数据的副本,再次获取数据时就不需要再执行 I/O,以此来避免 I/O(通常避免读取一些抽象的值)。缓存的关键在于要让哪些数据是主干的,哪些数据是副本变得显而易见。主干的数据只有一份(在一个更新周期里)。缓存有这样一种危险:副本有时候不能立刻反映主干的修改。 + +代表是通过更高效地表示数据来让 I/O 更廉价。这通常会限制其他的要求,比如可读性和可移植性。 + +代表通常可以用他们第一实现中的两到三个因子来做优化。实现这点的技术包括使用二进制表示而非人类可识别的方式,传递数据的同时也传递一个符号表,这样长的符号就不需要被编码,一个极端的例子是哈弗曼编码。 + +另一种有时能够用来优化本地引用的技术是让计算更接近数据。例如,如果你正在从数据库读取一些数据并且在它上面执行一些简单的计算,比如求和,试着让数据库服务器去做这件事,这高度依赖于你正在工作的系统的类型,但这个方面你必须自己探索。 + +Next [如何管理内存](09-How-to-Manage-Memory.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md b/zh-traditional/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md new file mode 100644 index 0000000..969f265 --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -0,0 +1,15 @@ +# 如何管理内存 +[//]: # (Version:1.0.0) +内存是一种你不可以耗尽的珍贵资源。在一段时期里,你可以无视它,但最终你必须决定如何管理内存。 + +堆内存是在单一子程序范围外,需要持续(保留)的空间。一大块内存,在没有东西指向它的时候,是无用的,因此被称为*垃圾*。根据你所使用的系统的不同,你可能需要自己显式释放将要变成垃圾的内存。更多时候你可能使用一个有*垃圾回收器*的系统。一个垃圾回收器会自己注意到垃圾的存在并且在不需要程序员做任何事情的情况下释放它的内存空间。垃圾回收器是奇妙的:它减小了错误,然后增加了代码的简洁性。如果可以的话,使用垃圾回收器。 + +但是即使有了垃圾回收机制,你还是可能把所有的内存填满垃圾。一个典型的错误是把哈希表作为一个缓存,但是忘了删除对哈希表的引用。因为引用仍然存在,被引用者是不可回收但却无用的。这就叫做*内存泄露*。你应该尽早发现并且修复内存泄露。如果你有一个长时间运行的系统,内存可能在测试中不会被耗尽,但可能在用户那里被耗尽。 + +创建新对象在任何系统里都是有点昂贵的。然而,在子程序里直接为局部变量分配内存通常很便宜,因为释放它的策略很简单。你应该避免不必要的对象创建。 + +当你可以定义你一次需要的数量的上界的时候,一个重要的情况出现了:如果这些对象都占用相同大小的内存,你可以使用单独的一块内存,或缓存,来持有所有的这些对象。你需要的对象可以在这个缓存里以循环的方式分配和释放,所以它有时候被称为环缓存。这通常比堆内存分配更快。(译者注:这也被称为对象池。) + +有时候你需要显式释放已分配的内存,所以它可以被重新分配而非依赖于垃圾回收机制。然后你必须谨慎机智地分配每一块内存,并且为它设计一种在合适的时候重新分配的方式。这种销毁的方式可能随着你创建的对象的不同而不同。你必须保证每个内存分配操作都与一个内存释放操作相匹配。(译者注:在C里面,no malloc no free,在C++里面,no new no delete)。这通常是很困难的,所以程序员通常会实现一种简单的方式或者垃圾回收机制,比如引用计数,来为它们做这件事情。 + +Next [如何处理偶现的 Bug](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md b/zh-traditional/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md new file mode 100644 index 0000000..3fb5f8a --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -0,0 +1,17 @@ +# 如何处理偶现的 Bugs +[//]: # (Version:1.0.0) +偶现 bug 是一种类似于外太空50足隐身蝎子的东西。这种噩梦是如此稀少以至于它很难观察,但其出现频率使得它不能被忽视。你不能调试因为你不能找到它。 + +尽管在8个小时后你会开始怀疑,偶现的 bug 必须像其他事情一样遵循相同的逻辑规律。但困难的是它只发生在一些未知的情形。尝试着去记录这个 bug 出现时的情景,这样你可以去推测到底是什么样的可变性。情况可能跟数据的值相关,比如“这只是在我们把*Wyoming*作为一个值输入时发生”,如果这不是可变性的根源,下一个怀疑应该是不合适的同步并发。 + +尝试,尝试,尝试去在一种可控的方式下重现这个 bug。如果你不能重现它,用日志系统给它设置一个圈套,来在你需要的时候,在它真的发生的时候,记录你猜想的,需要的东西。重新设计这个圈套,如果这个bug只发生在产品中,且不在你的猜想中的话,这可能是一个漫长的过程。你从日志中得到的(信息)可能不能提供解决方案,但可能给你足够的信息去优化这个日志。优化后的日志系统可能花很长时间才能被放入产品中使用。然后,你必须等待 bug 重新出现以获得更多的信息。这个循环可能会继续好几次。 + +我曾创建过的最愚蠢的偶现 bug 是在用一个函数式编程语言里为类工程做多线程实现的时候。我非常仔细地保证了函数式程序的并发估计, CPU 的充分使用(在这个例子里,是8个 CPU)。我却简单地忘记了去同步垃圾回收器。系统可能运行了很长一段时间,经常结束在我开始任何一个任务的时候,在任何能被注意到的事情出错之前。我很遗憾地承认在我理解我的错误之前,我甚至开始怀疑硬件了。 + +在工作中我们最近有这样一个偶现的 bug 让我们花了几个星期才发现。我们有一个多线程的基于 Apache™ 的 Java™web 服务器,在维护第一个页面跳转的时候,我们在四个独立线程而非页面跳转线程里,为一个小的集合执行所有的 I/O 操作。每一次跳转会产生明显的卡顿然后停止做任何有用的事情,直到几个小时后,我们的日志才让我们了解到底发生了什么。因为我们有四个线程,在一个线程内部发生这种情况并不是什么大问题,除非所有的四个线程都阻塞了。然后被这些线程排空的队列会迅速填充所有可用的内存,然后导致我们的服务器崩溃。这个 bug 花了我们一个星期去揪出这个问题,但我们仍然不知道什么导致了这个现象,不知道它什么时候会发生,甚至不知道它们阻塞的时候,线程们在干什么。 + +这表明了有关使用第三方软件的一些风险。我们在使用一段授权的代码,从文本中移除HTML标签。受它的起源的影响,我们把它叫做法国脱衣舞者。尽管我们有源代码(由衷感谢!),我们没有仔细研究它,直到查看我们服务器的日志的时候,我们最终意识到是“法国脱衣舞者”使邮件线程阻塞了。 + +这个工具在大多数时候工作得很好,除了处理一些长而不常见的文本时。在那些文本里,代码复杂度是 N 的平方或者更糟。这意味着处理时间与文本的长度的平方成正比。正式由于这些文本通常都会出现,所以我们才可以马上发现这个 bug。如果他们从来都不会出现,我们永远都不会发现这个问题。当它发生时,我们花了几个星期去最终理解并且解决了这个问题。 + +Next [如何学习设计技能](11-How-to-Learn-Design-Skills.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md b/zh-traditional/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md new file mode 100644 index 0000000..8f6498d --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -0,0 +1,9 @@ +# 如何学习设计技能 +[//]: # (Version:1.0.0) +为了学习如何设计软件,你可以在导师做设计的时候,在他身边学习他的行为。然后学习精心编写过的软件片段(译者注:比如 android 系统中的谷歌官方应用源码)。在这之后,你可以读一些关于最新设计技术的书。 + +然后你必须自己动手了。从一个小的工程开始,当你最后完成时,考虑为什么这个设计失败了或成功了,你是怎样偏离你最初的设想的。然后继续去着手大一点的工程,在与其他人合作时会更有希望。设计是一种需要花很多年去学习的关于评判的事情。一个聪明的程序员可以在两个月内充分打好这种基础,然后从这里开始进步。 + +发展出你自己的风格是自然而有用的,但记住,设计是一种艺术,而不是一种技术。人们写的关于这个主题的书都有一种使得它好像是技术的既定的兴趣。不要武断对待特定的设计风格。 + +Next [如何进行实验](12-How-to-Conduct-Experiments.md) diff --git a/zh-traditional/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md b/zh-traditional/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md new file mode 100644 index 0000000..c9fedec --- /dev/null +++ b/zh-traditional/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -0,0 +1,22 @@ +# 如何进行实验 +[//]: # (Version:1.0.0) +已故的伟大的 Edsger Dijkstra 曾经充分解释过:计算机科学不是一门实验科学[ExpCS],并且不依赖于电子计算机。当他提出这个观点时,他指的是19世纪60年代。[Knife] + +> ...危害已经出现:主题现在已经变成了“计算机科学” - 这实际上,像是把外科手术引用为“手术刀科学” - 这在人们心中深深植入了这样一个概念:计算机科学是关于机器和它们的外围设备的。 + +编程不应该是一门实验科学,但大多数职业程序员并没有保卫 Dijkstra 对于计算机科学的解释的荣耀。我们必须在实验的领域里工作,正如一部分,但非所有的物理学家做的那样。如果三十年后,编程可以在不进行任何实验的前提下进行,这将是计算机科学的一个巨大成就。 + +你需要进行的实验包括: +- 用小的例子测试系统以验证它们遵循文档,或者在没有文档时,理解它们的反应; +- 测试一些小的代码修改去验证它们是否确实修复了一个 bug; +- 由于对一个系统不完全的理解,需要在两种不同情况下测量它们的性能表现; +- 检查数据的完整性; +- 对困难的或者难以重现的 bug,收集解决方案中可能提示的统计数据。 + +我不认为在这篇文章里我可以讲述实验的设计,你会在实践中学习到这方面的知识。然而,我可以提供两点建议: + +第一,对你的假设或者你要测试的断言要非常清楚。把假设写下来也是很有用的,尤其是如果你有点迷惑或者与其他人合作时。 + +第二,你会经常发现你必须设计一系列的实验,它们中的每个都基于对最后一个实验的理解。所以,你应该设计你的实验尽量去提供最多的信息。但不幸的是,这会让实验保持简单变的困难 - 你必须通过经验来提升这种权衡的能力。 + +Next [团队技能 - 为什么评估很重要](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/zh-traditional/1-Beginner/README.md b/zh-traditional/1-Beginner/README.md new file mode 100644 index 0000000..d5dc54c --- /dev/null +++ b/zh-traditional/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. 入门 +[//]: # (Version:1.0.0) +- 个人技能 + - [学会 Debug](Personal-Skills/01-Learn-To-Debug.md) + - [如何通过分割问题 Debug](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一个错误](Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日志调试](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能问题](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解决性能问题](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何优化循环](Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何处理 I/O 开销](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理内存](Personal-Skills/09-How-to-Manage-Memory.md) + - [如何处理偶现的 Bug](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何学习设计技能](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何进行实验](Personal-Skills/12-How-to-Conduct-Experiments.md) +- 团队技能 + - [为什么预估很重要](Team-Skills/01-Why-Estimation-is-Important.md) + - [如何预估编程时间](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人们作为信息源](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何优雅地写文档](Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代码上工作](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代码控制](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何进行单元测试](Team-Skills/08-How-to-Unit-Test.md) + - [毫无头绪?休息一下](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何决定下班时间](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何与不好相处的人相处](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md b/zh-traditional/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md new file mode 100644 index 0000000..e3cdb96 --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -0,0 +1,14 @@ +# 为什么评估很重要 +[//]: # (Version:1.0.0) +为了尽快获得一个可以高效使用的工作软件系统,不仅需要为开发做计划,还需要为文档,部署,市场做计划。在一个商业工程里,这还需要销售和金融计划。没有对开发时间的预测能力,是不可能高效预测以上这些东西的。 + +好的估计提供了预测能力。管理者喜欢,而且应该这么做。事实是这不可能,不论是理论上还是实践上,准确预测开发软件所消耗的时间总是被管理者所忽视。我们总是被要求做那些不可能的事情,而且我们必须诚实地面对它。不论如何,不承认这个任务的不可能性也是不诚实的,必要的时候,需要解释。对于评估来说,会产生很多沟通不畅的情况,因为人们令人吃惊地倾向于一厢情愿地认为下面这句话: +> 我估计,如果我确实理解了这个问题,我们在5周内有50%的可能完成任务(如果在此期间没有人干扰我们的话)。 + +的真实的含义是: + +> 我保证从现在开始五个星期内完成任务。 + +这个常见的解读问题需要你与你的 boss 和客户明确地讨论(就好像把他们当做傻子那样)。重新阐述你的解释,不管对你来讲它们有多么显而易见。 + +Next [如何估计编程时间](02-How-to-Estimate-Programming-Time.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md b/zh-traditional/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md new file mode 100644 index 0000000..a2764bf --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -0,0 +1,21 @@ +# 如何评估编程时间 +[//]: # (Version:1.0.0) +评估需要实践,也需要劳动。因为它需要花如此长的时间,以至于评估评估本身的时间可能是一个好主意,尤其是你被要求去评估一些巨大的事情。 + +当被要求评估一些比较大的事情的时候,该做的最可靠的事情是先停下来。大多数工程师是充满热情并且是渴望愉悦的,而停下来当然会让他们不开心。但对一个进行中的事情做评估一般是不准确且不可靠的。 + +停下来,使得考虑一些事情或者为任务重新定型成为可能。如果政策压力允许,这是执行评估的最准确的方式,并且它会产生确实的进度。 + +在没有时间做调查的时候,你首先应该非常清晰地建立评估的含义。首先重新阐述要评估的内容和你编写的评估的最后部分。在你准备编写评估的时候应该把这项任务分解为一个个更小的循序渐进的任务,并且使每个小任务需要的时间不超过一天(理想情况是每个任务的长度最多为一天)。最重要的事情是不要漏掉任何事情。例如,文档,测试,规划的时间,与其他小组交流的时间,还有度假时间,这些都是很重要的。如果你每天都要花时间和一些傻逼交流,在评估里为这件事情划一个明确的时间界限。这能让你的boss对于你将要花费的最少时间有了一个认识,并且可能给你更多的时间。 + +我认识一些会隐式地填充评估时间的好的程序员,但我推荐你不要这样做。填充的一个结果是你可能会耗尽别人对你的信任。例如,一个工程师可能为一个将要花费一天的工作评估为三天。这个工程师可能计划花两天去为代码写文档,或者花两天去做一些其他有用的工程。但当任务在一天内完成时,如果它在那天暴露出来的话,这是可以察觉的,并且松懈或高估的表现会出现。为你确实要做的事情做合适的剖析要好得多。如果写文档需要花两倍于编程的时间,并且评估的结果就是这样的,让这对管理者可见就能得到巨大的好处。 + +相反,显式填充。如果一个任务可能花一天,但如果你的方法没有生效,可能花十天 - 用某种方式在你的评估里记下这个情况,否则,至少为这个可能性,评估一个权重计算可能的时间。任何你可以识别和进行评估的风险因素应该在时间表里被体现。一个人不太可能在给定的任何星期都生病。但一个有很多工程师的大项目可能会有一些疾病时间,还有休假时间。或者,是否会有公司内部的强制培训研讨会的可能性呢?如果这可以预估,也把它算进来。当然,还有一些未知的未知,或者 [unk-unk](../../4-Glossary.md) 。Unk-unk 在定义上是不能被独立评估的。你可以尝试为所有 unk-unk 创建一个全局的界线,或者用你与你的 boss 交流好的其他方式去处理它们。然而,你不能让你的 boss 忘记它们的存在。在把评估变成时间表的过程中,把它们遗忘是超级容易的。 + +在一个团队环境里,你应该让任务的执行者去做这种评估,而且你们应该在团队范围内对评估的结果达成一致。人与人在技术,经验,准备和信心上都有很多的不同。当一个牛逼的程序员为他自己评估了时间,然后一些弱一点的程序员被这种评估约束时,灾难就会降临。整个团队在一个一行一行的细致的评估计划上取得的一致,阐述了团队的理解,以及允许在策略上对资源的重新分配的机会(比如,把负担从弱一点的团队成员那里移到强一点的成员那里)。 + +如果有不能评估的大风险,你应该无论如何都要提出来,这是你的责任,这让才能让管理者不会在这个问题上做承诺,以免在风险发生时让管理者难堪。这种情况下,任何需要的事情都有希望被执行来减小这个风险。 + +如果你可以说服你的公司去使用*极限编程*,你只需要评估相当小的事情,这也是更加有趣和有效率的。 + +Next [如何发现信息](03-How-to-Find-Out-Information.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md b/zh-traditional/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md new file mode 100644 index 0000000..b9613fa --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -0,0 +1,19 @@ +# 如何发现信息 +[//]: # (Version:1.0.0) +你所搜寻的事情的本质决定了你应该如何去寻找它。 + +如果你需要客观的而且容易辨认的*关于具体事物*的信息,例如一个软件的最新补丁版本,可以在Internet搜索,礼貌的询问很多的人,或者发起一个讨论组。不要在网上搜索任何带有观点或主观解释的东西:能够抵达真相的概率太低了。 + +如果你需要“一些主观的普遍知识”,人们对这些东西已有的思考历史,那就去图书馆吧。例如,想要了解数学,蘑菇或着神秘主义,就去图书馆吧。 + +如果你需要知道*如何做一些琐碎的事情*,找两三本关于这个主题的书,仔细阅读。你可以从网络上学到如何做好这些琐碎的事情,比如安装一个软件包。你甚至可以学到一些重要的东西,例如好的编程技术,但相比读一本纸质书的相关部分,你很容易花更多时间在搜索和对结果排序,以及评估结果的权威性。 + +如果你需要*可能没有人知道的信息*,例如,“这个新品牌的软件在海量数据的情况下能工作吗”,你仍然必须在网络和图书馆里搜索。在这些选项都完全竭尽后,你可能需要设计一个实验来搞清楚这个问题。 + +如果你需要一些考虑了某些特殊环境的观点或估值,和一个专家聊聊。例如,如果你想要知道用 Lisp 构建一个现代数据库管理系统是否是一个好主意,你应该和一个 Lisp 专家和一个数据库专家聊一聊。 + +如果你想要知道*它具体是怎样的*,比如一个还未发布的在一个特定程序上更快的算法,跟一些在这个领域工作的人聊聊。 + +如果你想要做一个*只有你自己能做的个人决定*,比如你是否应该开始某个事业,尝试把一些对这个想法有益和有害的点列出来。如果这没有什么用,做一些预测。假设你已经从各个角度研究了这个想法,并且做了所有该做的准备,在心里列举所有的后果,包括好的和坏的,但你仍可能犹豫不决。你现在应该遵循你自己内心的想法,然后让你的大脑停止思考。大多数可用的预测技术都对决定你内心一半的欲望有作用,因为它们在体现你自己完全多义和随机模式的潜意识都很有用。 + +Next [如何将人们作为信息源](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md b/zh-traditional/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md new file mode 100644 index 0000000..73723cb --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -0,0 +1,15 @@ +# 如何把人们作为信息源 +[//]: # (Version:1.0.0) +尊重其他每个人的时间,与你的时间相平衡。问别人问题比得到答案能获得更多。人们会从你的存在和倾听特定的问题从你身上学到东西。你也可以用同样的方式从别人身上学习到东西,你可能学到你正在搜寻的东西的答案。这通常比你的问题更加重要得多。 + +然而,这个问题的价值会减少你在上面做的事情。你毕竟使用了一个人拥有的最珍贵的商品:时间。交流的好处必须与代价相权衡。更进一步,特定的代价和好处在人与人之间都不一样。我强烈相信一个100人的管理者每个月应该花五分钟与他所在的组织的每个人谈话,大概是它们的时间的5%。但十分钟可能太多了,如果他们有1000个员工,5分钟也可能太多了。你与组织中每个人交谈花费的时间取决于他们的角色(而非他们的位置)。你应该和你的 boss 交谈而非和你 boss 的 boss 交谈,但你偶尔也可以和你 boss 的 boss 交谈啦。这可能不太舒服,但我相信你有责任每个月和你的上上级稍微聊聊,什么都行。 + +基本的规则是,每个与你交谈的人都能稍微受益,他们与你聊得更多,他们能获得的收益越少。你的应该给他们提供这种好处,还有得到与他们交流的好处,平衡这种好处与花费的时间。 + +尊重你自己的时间是很重要的。如果和一些人聊天,即使这会消耗他们的时间,结果会节省你很多的时间,那么你应该这样做,除非你认为他们的时间在这个因素上,对整个集体,比你的时间更加有价值。 + +一个奇怪的例子是暑期实习生。一个处于高技术含量位置的暑期实习生不能被期望去完成太多东西;他们可能会把每个人纠缠到地狱。但为什么这是被允许的呢?因为被纠缠的人从实习生身上可以接收到一些重要的东西。他们得到了一点炫耀的机会,他们可能有机会去听到一些新的思想,他们有机会可以从不同的角度去看问题。他们可能会尝试招聘这个实习生,但即使不是这样,他们也获得了很多。 + +如果你真诚地相信别人有一些东西可以告诉你,无论合适,应该询问他们的意见与智慧。这能让他们高兴并且你可以从他们身上学到一些东西,也可以教会他们一些东西。一个好的程序员不会经常需要销售副经理的建议,但如果你需要,你当然应该询问这个问题。我曾经被要求去倾听一些销售电话以便更好地理解我们的销售员工的工作。这不会耗费超过30分钟,但却让我通过这么小的付出就对公司的销售队伍有了深刻的印象。 + +Next [如何优雅地写文档](05-How-to-Document-Wisely.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md b/zh-traditional/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md new file mode 100644 index 0000000..caccfbc --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -0,0 +1,20 @@ +# 如何睿智地写文档 +[//]: # (Version:1.0.0) +人生太短,不能写没人会读的废话,如果你写了废话,没人会去读。所以好一点的文档是最好的。经理不会去理解这些东西,因为不好的文档会给他们错误的安全感以至于他们不敢依赖他们的程序员。如果一些人绝对坚持你真的在写没用的文档,就告诉他们“是的”,然后安静的找一份更好的工作。 + +没有其他事情比精确估计 把好的文档转为放松文档要求的估计 更为有效率。真相是冷酷而艰难的:文档,就像测试,会花比开发代码多几倍的时间。 + +首先,写好的文档是好的写作。我建议你找一些关于写作的事情,学习,练习他们。但即使你是一个糟糕的写手或者对你需要写文档的语言掌握不好,这条黄金规则是你真正需要的:己所不欲,勿施于人。花时间去确实地思考谁会读你的文档,他们从文档中想要获得的真正的东西是什么,并且你可以如何把这些东西交给他们。如果你这样做,你将会变成一个超过平均水平的文档编写者,和一个好的程序员。 + +当代码可以自成文档时,与提供文档给非程序员看相反,我认识的最好的程序员们有这样一个普遍的观点:编写具有自我解释功能的代码,仅在你不能通过代码清晰解释其含义的地方,才写注释。有两个好的原因:第一,任何人需要查看代码级别的文档大多数情况下都能够并且更喜欢阅读代码。不可否认的,有经验的程序员似乎比初学者更容易做到这件事,然而,更重要的是,没有文档的话,代码和文档不会是自相矛盾的。源代码最糟糕的情况下可能是错误并且令人困惑的。没有完美编写的文档,可能说谎,这可糟糕一千倍。 + +负责任的程序员也不能让这件事变得更简单些。如何写自解释的代码?那意味着什么?它意味着: + +- 编写知道别人会去阅读的代码(译者注:编写给人看的代码) +- 运用黄金法则 +- 选择直接的解决方案,即使你可以更快地获得另一个解决方案 +- 牺牲那些可能混淆代码的小的优化 +- 为读者考虑,把你珍贵的时间花在让她更加容易阅读的事情上,并且 +- 永远不要使用这样的函数名比如 `foo`,`bar`, 或 `doIt`! + +Next [如何在糟糕的代码上工作](06-How-to-Work-with-Poor-Code.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md b/zh-traditional/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md new file mode 100644 index 0000000..a7ecd95 --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -0,0 +1,11 @@ +# 如何在糟糕的代码上工作 +[//]: # (Version:1.0.0) +工作在别人写的糟糕的代码上是常有的事。不要把他们想得太糟,直到你用他们的鞋子走路时。他们可能被要求非常自觉地快速完成一些东西来满足时间表的压力。不管之前发生了什么,为了在不清晰的代码上工作,你必须理解它。理解它需要花费一些学习时间,你必须坚持从时间表中某些部分划出一部分时间来做这件事。为了理解它们,你必须读源代码,你可能需要在上面做一些实验。 + +即使是为你自己,编写文档也是一个好的时机,因为尝试为你的代码编写文档会强迫你从你可能没有考虑过的角度思考,并且完成的文档可能会有用。当你在做这个时,考虑重写部分或所有代码会消耗你什么东西。是否重写一部分代码事实上真的会节省时间?你重写代码后你会更信任它吗?在这里小心你的傲慢。如果你重写它,你处理它会更容易,但下一个必须阅读它的人是否真的更加容易?如果你重写了,测试的负担在哪里?重新测试的需要是否大于可能获得的好处? + +在任何对你没有编写的代码的评估中,代码的质量会影响你对风险问题的认识以及一些未知的事情。 + +铭记抽象和封装是很重要的,这两个程序员最好的工具,对糟糕的代码是特别好用的。你可能不能够重新设计一大块代码,但如果你可以为它增加一定量的抽象,你不用重新在这整团迷雾上工作就可以获一些好的设计所带来的好处。特别的,你可以尝试去隔离尤其糟糕的代码,这样他们就可以被独立重构。 + +Next [如何使用源代码控制](07-How-to-Use-Source-Code-Control.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md b/zh-traditional/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md new file mode 100644 index 0000000..0d923ba --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -0,0 +1,9 @@ +# 如何使用源代码控制 +[//]: # (Version:1.0.0) +源代码控制系统(又称版本控制系统)让你高效地管理工程。他们对一个人是很有用的,对一个团队是至关重要的。它们追踪不同版本里的所有改变,以至于所有代码都未曾丢失,其含义可以归属于改变。有了源代码控制系统,一个人可以自信地写一些而半途而废的代码和调试的代码,因为你修改的代码被仔细地与提交的、官方的即将与团队共享或发布的代码分割开。 + +我挺晚才开始意识到源代码控制系统的好处,但现在即使是一个人的工程,我也不能离开源代码控制系统。当你们团队在同样的代码基础上工作时,通常它们是必要的。然而,它们有另一个巨大的优点:它们鼓励我们把代码当做一个成长的有机系统。因为每个改变都会被标记为带有名字或数字的修正,一个人会开始认为软件是一种可见的一系列渐进的提升。我认为这对初学者是尤其有用的。 + +使用源代码控制系统的一个好的技术是一直保持在几天后提交更新。在提交后,一定程度上不活跃,不被调用的代码在几天内都不会完成,因此也不会对其他任何人产生任何问题。因提交错误的代码而降低你队友的开发速度是一个严重的错误,这往往是一种禁忌。 + +Next [如何进行单元测试](08-How-to-Unit-Test.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/08-How-to-Unit-Test.md b/zh-traditional/1-Beginner/Team-Skills/08-How-to-Unit-Test.md new file mode 100644 index 0000000..54c105a --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -0,0 +1,9 @@ +# 如何进行单元测试 +[//]: # (Version:1.0.0) +单元测试,对独立的代码功能片段,由编写代码的团队进行测试,也是一种编码,而非与之不同的一些事情。设计代码的一部分就是设计它该如何被测试。你应该写一个测试计划,即使它只是一句话。有时候测试很简单:“这个按钮看起来好吗?”,有时候它很复杂:“这个匹配算法可以精确地返回正确的匹配结果?”。 + +无论任何可能的时候,使用断言检查以及测试驱动。这不仅能尽早发现 bug,而且在之后也很有用,让你在其他方面担心的谜题得到解决。 + +极限编程开发者广泛高效地编写单元测试,除了推荐他们的作品,我不能做更好的事情了。 + +Next [毫无头绪?休息一下](09-Take-Breaks-when-Stumped.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md b/zh-traditional/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md new file mode 100644 index 0000000..c79ff59 --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -0,0 +1,5 @@ +# 毫无头绪?,休息一下 +[//]: # (Version:1.0.0) +没有思路时,休息一下。我有时候没有思路时会冥思15分钟,当我回来看问题时,它就神奇地解开了。更大尺度上,一个晚上的睡眠能做到一样的事情,临时切换到其他活动上可能也会有效。 + +Next [如何决定下班时间](10-How-to-Recognize-When-to-Go-Home.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md b/zh-traditional/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md new file mode 100644 index 0000000..0845f8e --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -0,0 +1,15 @@ +# 如何识别下班时间 +[//]: # (Version:1.0.0) +计算机编程是一种活动也是一种文化。不幸的事实是它不是一种看重身心健康的文化。从文化/历史缘由看(例如,在机器空载的晚上工作的需要),还有因为超过市场时间的压力和程序员的缺乏,计算机程序员传统上总是过度工作。我不认为你可以相信你听到的所有故事,但我认为一周工作60小时是常见的,50小时更多的像一个最小值。这意味着实际总是比需要的时间花费得更多。这对一个好的,不仅为他们自己负责而且为他们的同事负责的程序员来说是一个严重的问题。你需要识别什么时候下班,有时候还要建议其他人回家的时间。解决这个问题的固定规则不存在,抚养一个孩子的固定规则也是,出于同样的原因---每个人都是不同的。 + +一周超过60个小时工作对我来说是非常辛苦的,我可以申请挺短的一段时间(大概是一周),有时候在我的预料中。我不知道对一个人来说一周工作超过60小时是否公平,我甚至不知道40小时是否是公平的。然而,我确定,如果你努力工作,却在你额外工作的时间里获得了很少东西,这是很愚蠢的。对我个人来说,我认为做一个懦夫不是一个程序员该做的事。遗憾的是,事实上,程序员经常*被*要求做一个懦夫来为一些人表演,例如一个经理想要给总经理留下深刻印象。程序员经常对此屈服,因为他们希望开心,并且不善拒绝,与此相反的有四道防护墙: +- 尽可能与公司里的任何人交流,这样没人可以误导总经理正在发生的事情; +- 学习明确而防御性地评估和规划,让每个人看到时间表的内容以及它的立场; +- 学会拒绝,在必要时作为一个团队拒绝,并且 +- 如果必须的话,退出团队 + +大多数程序员是好的程序员,好的程序员想要做很多东西。为了做到这点,他们需要高效管理他们的时间。从一个问题中兴奋和深陷其中都有一定量的心理惯性。许多程序员发现他们在长久不被打扰的一段时间里能够保持兴奋和集中注意力,这让他们能最好地工作。然而,人们必须睡觉,并且有其他的责任。每个人需要找到一种方式去满足他们的生物节奏和工作节奏。每个程序员需要做任何必须的事情来提供高效的工作周期,比如只参加的某些最关键的会议,以此保留一定的时间。 + +因为我有孩子,我尝试和他们在晚上相处。我自己最好的工作节奏是工作很长的一天,在办公室或办公室附近睡觉(从家到工作我需要很长的转换时间)然后足够早地回家,在我的孩子们睡觉前与他们相处。我觉得这并不舒服,但这是我可以工作的最好的妥协。如果你得了传染病,回家。如果你有自杀的想法,回家。如果你有超过几秒的凶杀的想法,回家。如果有人有严重的心理障碍或者超出心情低落的心理疾病的标志,把他送回家。如果你由于疲劳变得与平时不同地在某种程度上趋于不诚实或失望,休息一下。不要使用药物缓解疲劳。不要滥用咖啡因。 + +Next [如何与不好相处的人相处](11-How-to-Deal-with-Difficult-People.md) diff --git a/zh-traditional/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md b/zh-traditional/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md new file mode 100644 index 0000000..6d20e15 --- /dev/null +++ b/zh-traditional/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -0,0 +1,15 @@ +# 如何与不好相处的人相处 +[//]: # (Version:1.0.0) +你可能必须和不好相处的人相处。甚至可能你本身就是一个不好相处的人。如果你是那种与同事和权威人物有许多矛盾的人,你应该珍惜这种独立所暗示的东西,但需要在不牺牲你的智力或原则的前提下提高你的人际交往能力。 + +在这方面没有什么经验,或者先前生活的行为模式在工作场合的经验不能适用的一些程序员,对这种事情会非常困扰。不好相处的人经常习惯于拒绝,并且与他人相比,他们更不容易受社交压力所影响。关键是合适地尊重他们,而非你可能想做的事,但不要充分地满足他们想要的(译者注:他们想要的往往是过分的)。 + +程序员必须作为一个团队一起工作。当分歧出现时,它必须用某种方式解决,它不能被长时间挂起。不好相处的人通常是极度聪明的,并且有一些很有用的意见可以发表。不带对这个人的偏见,倾听并理解不好相处的人是至关重要的。失败的交流通常是分歧的基础,但它有时候可以被巨大的耐心移除。尝试冷静诚恳地保持交流,并且不接受任何可能产生更大矛盾的引诱。在一个合理的尝试理解的周期后,再做决定。 + +不要让一个恶霸强迫你做你所不同意的事情。如果你是老大,做你认为最好的事情。不要为任何个人因素做出决定,并时刻准备好为你的决定做出解释。如果你是一个有着不好相处的同事的团队成员,不要让老大的决定有任何个人影响。如果没有按你的想法发展,全身心地按(已成事实的)另一种方法去做。 + +不好相处的人能够改变与进步。我曾亲眼目睹这种情况,但这很稀少。然而,每个人都有暂时的高兴与失落情绪。 + +每个程序员但尤其是领导都会面临这样一个挑战:让不好相处的人保持完全的忙碌。他们比别人更倾向于枯燥的工作,并且更能被动地忍受。 + +Next [进阶技能](../../2-Intermediate) diff --git a/zh-traditional/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md b/zh-traditional/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md new file mode 100644 index 0000000..315f40f --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -0,0 +1,13 @@ +# 如何在开发质量与开发时间权衡 +[//]: # (Version:1.0.0) +软件开发总是在工程该做什么与完成工程间妥协。但你可能被要求以牺牲你的工程适用性或商业适用性的方式,去交换工程的开发速度。例如,你可能被要求做一些糟糕的软件工程实践,但这将会导致大量维护问题。 + +如果这发生了,你的首要任务是通知你的团队,然后清楚地解释降低质量的代价。在这之后,你对这个问题的理解会比你的 boss 的理解还要更清晰。明白将会失去什么以及将要得到什么,以及在这次失去的东西,能在下一轮中得到什么。在这个过程中,由一个好工程提供的可见性应该会很有用。如果用质量换时间影响了质量保证工作,(向你的 boss 和质量保证人员)指出这个问题。如果用质量换时间会导致在之后的质量保证周期中出现更多的 bug,指出来。 + +如果她仍然坚持,你应该把劣质部分隔离到特殊的你可以在下一个开发周期计划重写或优化的组件中。向你的团队解释这个问题,这样他们可以为此做些计划。 + +忍者程序员在 Slashdot 写下了这样的格言: + +> 记住,一个好的设计会被糟糕的代码实现弹回。如果好的接口和抽象在代码中到处存在,最后的重写会更加痛苦。如果写难以修复的清晰代码很困难,考虑是什么与核心设计冲突的东西导致了这个问题。 + +Next [如何管理软件依赖](02-How-to-Manage-Software-System-Dependence.md) diff --git a/zh-traditional/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md b/zh-traditional/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md new file mode 100644 index 0000000..635f956 --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -0,0 +1,13 @@ +# 如何管理软件系统依赖 +[//]: # (Version:1.0.0) +现代软件系统趋向于依赖大量的非直接可控的组件。通过协同与重用,这增加了生产效率。然而,每个组件会带来一些问题: + +- 你该如何修复组件中的 bug? +- 组件限制你使用特殊的硬件或软件系统了吗? +- 如果组件完全坏掉了,你该做什么? + +某些程度上解耦组件,让它独立可以被移除,总是最好的。如果组件被证明完全不可用,你可能能够使用不同的组件,但你可能必须自己写一个组件。解耦不是可移植性,但这让移植变得简单,这大多数时候是好事。 + +拥有组件源代码可以把风险降到1/4.有了源代码,你可以更容易地评估它,调试它,找到避免踩坑的方法,并且使得修复更容易。如果你进行修复,你必须把修复的内容提交给组件的拥有者,并且让修改合并到官方发布版中,否则你将不适地必须维护一个非官方版本。 + +Next [如何判断软件是否太不成熟了](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/zh-traditional/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md b/zh-traditional/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md new file mode 100644 index 0000000..09e7170 --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -0,0 +1,18 @@ +# 如何判断软件是否太不成熟了 +[//]: # (Version:1.0.0) +使用其他人写的软件是一种最有效率的构建一个坚实的系统的方法之一。这本不该被排斥,但与此相关的风险必须被检验。最大的一种风险在于,它通过使用变成一个可用产品成熟前的 bug 周期和与软件相关的故障时期。在你考虑将软件系统集成前,不论是你自己写的还是第三方的,考虑它是否足够成熟以使用是非常重要的。这里有十个你应该自问的相关问题: + +1. 它是蒸汽吗?(那肯定是不成熟的) +2. 有可用的懂这个软件的人吗? +3. 你是第一使用者吗? +4. 有持续使用的强烈动机吗? +5. 有维护负担吗? +6. 没有当前的维护者的话,它还能用吗? +7. 有至少和它的一半那样好的经验丰富的其他可用途径? +8. 你的团队或公司了解它吗? +9. 你的团队或公司对它满意吗? +10. 即使它不好,你可以雇人在它上面工作吗? + +对这些标准的一点考虑论证了良好构建的自由软件和开源软件在减小企业家风险上的巨大价值 + +Next [如何做一个购买或构建决定](04-How-to-Make-a-Buy-vs-Build-Decision.md) diff --git a/zh-traditional/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md b/zh-traditional/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md new file mode 100644 index 0000000..764e06f --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -0,0 +1,16 @@ +# 如何做购买还是构建的决定 +[//]: # (Version:1.0.0) +一个尝试用软件完成一些任务的企业级公司或工程必须不断做所谓的 *buy vs. build* 的决定。这个问题的不幸在两个方面:似乎忽视了不必*被购买*的开源软件和自由软件。更重要的是,这可能应该被称作*获取与集成 vs. 购买与集成*决定,因为集成的代价需要被考虑。这需要商业上,管理上,工程理解上的大量结合。 + +- 你的需要与它的设计意图有多接近? +- 对于你购买的软件,你想要怎样的可移植性? +- 评估集成的代价是什么? +- 集成的代价是什么? +- 购买会增加还是减少长期维护代价? +- 构建会把你放在一个你不想要的商业位置吗? + +在你构建一些大到足够成为另一整个商品的基础的东西前请三思。这样的想法通常是乐观积极的将会对你的团队做出许多贡献的人提出来的。如果他们的想法很引人注目,你可能会想要改变你的商业计划,但不要在没有周全考虑前就投资一个比你自己的商业还大的解决方案。 + +在考虑了这些问题后,你可能应当准备两个工程计划草案,一个给购买,一个给构建。这会强迫你考虑集成代价。你也应当考虑两种措施的长期维护代价。为了评估集成代价,你必须在购买软件前对它做一个彻底的评估。如果你不能评估好它,你可以假设购买它会有一个不可预料的风险,你应该以此决定是否购买特定的产品。如果考虑后有几个购买决定,需要花一些精力去评估每个决定。 + +Next [如何专业地成长](05-How-to-Grow-Professionally.md) diff --git a/zh-traditional/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md b/zh-traditional/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md new file mode 100644 index 0000000..779f1de --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -0,0 +1,11 @@ +# 如何专业地成长 +[//]: # (Version:1.0.0) +承担超过你的权力的责任。扮演你想要扮演的角色。对那些对更大组织的成功做出过贡献以及对你个人提供过帮助的人表示感谢与欣赏。 + +如果你想成为团队的领导,去激励与团结。如果你想成为一个经理,担起规划的责任。你通常可以在和领导或经理在一起时,舒服地完成这些事情,因为这使得他们可以抽空去承担更大的责任。如果这太多了以至于你不能尝试,一次只做一点点。 + +评估你自己。如果你想要变成一个好的程序员,询问一些你欣赏的人你怎样才能变成他们那样。你也可以问你的 boss,他可以告诉你的东西会少一些,但对你的事业会有更大的影响。 + +计划学习新技能的方式,包括琐碎的技术类型,比如学习一个新的软件系统,和困难的社交类型,像漂亮的写作,把它们集成到你的工作中。 + +Next [如何评估面试者](06-How-to-Evaluate-Interviewees.md) diff --git a/zh-traditional/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md b/zh-traditional/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md new file mode 100644 index 0000000..743bb37 --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -0,0 +1,15 @@ +# 如何评估面试者 +[//]: # (Version:1.0.0) +评估可能的员工,却没有得到它应得的能量。一个糟糕的雇佣,就像糟糕的婚姻,是非常糟糕的。每个人首要的一部分精力应该投入到招聘上,尽管这很少发生。 + +有不同的面试风格。有的是折磨人的,设计用来把候选人放在巨大压力下。这是为了这样一个有用的目的:在压力下折射出性格缺陷和弱点。候选人对待面试官不会比对待他们自己更诚实,而且,人的自欺能力是令人惊奇的。 + +你应当,最少,对候选人进行两个小时的与口头考核等价的技术技能考核。实践后,你会能够快速了解他们知道什么,快速收缩他们不知道的来标明边界。面试者会尊重这件事情。我有几次听面试者说面试的质量是他们选择公司的一个动机。聪明人会因他们的技能而被雇佣,而非他们之前工作过的地方或他们上了哪个学校或者一些无关紧要的特征。 + +做这些事情,你也应当评估他们的学习能力,这比他们所知道的要更加重要得多。你也应当留心那些难以相处的人所散发出的火药味。你可能能够在面试后通过比较笔记来识别这一点,但在面试的热烈环境中这很难分辨。人们交流的能力以及与人合作的能力比在最新的编程语言上领先更为重要。 + +一个读者有“在家”测验面试的经验。这有一个优点是揭露了一些面试者能良好地自我表现但不能写代码 - 这样的人是很多的。我个人没有尝试过这种技术,但这听起来挺合适的。 + +最后,面试也是一个销售的过程。你应该把你的公司或工程销售给候选人。然而,你是在与程序员谈话,所以不要尝试改变事实。从坏的事物开始讲起,最后以好的事物作为强有力的结束。 + +Next [怎么决定什么时候使用奇妙的计算机科学](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/zh-traditional/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md b/zh-traditional/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md new file mode 100644 index 0000000..92e2e94 --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -0,0 +1,15 @@ +# 如何决定什么时候使用奇妙的计算机科学 +[//]: # (Version:1.0.0) +有这样一些,例如算法,数据结构,数学,还有其他极客范的大多数程序员知道但很少使用的东西。实践中,这种奇妙的东西太复杂了,通常是不需要的。例如,当你花费大多数时间在低效的数据库调用上时,提高算法是没有什么用的。不幸的大量编程由让系统相互交流以及使用非常简单的数据结构去构建漂亮的用户界面组成。 + +高科技什么时候是合适的科技?你什么时候应当打开一本书去找一些东西而非一个毫秒级算法?做这些有时候是有用的,但这需要被小心评估。 + +对于潜在的计算机技术三个最重要的考虑是: + +- 它是否充分封装所以其他低级系统风险和复杂度过量增加以及维护代价很低? +- 好处是否是令人惊奇的(例如,成熟系统的两倍或新系统的十倍?) +- 你能够高效测试和评估它吗? + +如果一个充分独立算法使用了些许奇妙的可以减少硬件消耗或增加整个系统的两倍性能表现的算法,不考虑它可能是有罪的。争论这样一个方法的一个关键是,证明风险确实是相当的低,因为目标技术可能被充分研究过了,唯一的话题是集成的风险。在这里一个程序员的经验和评估能够真的协同奇妙的算法让集成变得容易。 + +Next [如何与非工程师交谈](08-How-to-Talk-to-Non-Engineers.md) diff --git a/zh-traditional/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md b/zh-traditional/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md new file mode 100644 index 0000000..d336760 --- /dev/null +++ b/zh-traditional/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -0,0 +1,19 @@ +# 如何与非工程师交谈 +[//]: # (Version:1.0.0) +工程师和程序员(尤其是)通常被主流文化认为与他人不同。这意味着其他人与我们不同。与非工程师交流时,这是值得记在心里的,你应该时刻去理解观众。 + +非工程师聪明,但在创造技术类的东西不像我们那样踏实。我们制造东西。他们销售,处理,统计,管理,但他们在制造上不是专家。他们不像工程师那样擅长团队合作(毫无疑问会有例外。)他们的社交技能在非团队环境里通常像工程师那样,甚至比工程师要好,但他们的工作不总要求他们像我们那样进行亲密,珍贵的交流,以及细致的任务划分。 + +非工程师可能太渴望以至于不能被取悦和与你亲近,他们可能在不是真的对你满意的时候却对你说“是”,或者是因为他们有点怕你,然后不会对你说实话。 + +非工程师可以理解技术的东西,但他们不会做那件甚至对我们来讲都很困难的事情 - 技术评审。他们确实理解技术是如何工作的,但他们不能理解为什么一个特定的方法需要花三个月而另一种方法要花三天。(毕竟,程序员对这种估计也感到事多得可怕。)这相当于一个巨大的和他们协作的机会。 + +与你的团队交谈时,你会不假思索地使用某种程度上的简略表达方式,一种简单的语言更有效率,因为你通常对技术或者特别是你的产品会有许多的共享经验。对于那些没有这些共享经验的人不使用简略表达方式是需要作出一些努力的,特别是你团队内部的人员也在场的时候。这些简略的词汇会让你与那些没有分享到相关经验的人之间构建出一道墙,甚至更糟的是,浪费着他们的时间。 + +与你的团队一起,基本的假设和目标不需要经常重申,大多数谈话集中于细节。与外人一起,就是另一回事了。他们可能不理解你认为理所当然的东西。由于你把这当做理所当然,并且没有重申它们,使得你们的谈话陷入这样一种情况:你可能认为你们相互理解,但事实上有一个巨大的误解。你应当假设你会有错误的交流,并且仔细观察去找出这样的误解。试着总结或将你说的东西分点,来确保他们能够理解。如果你有机会经常与他们见面,花一点时间询问你是否在有效地交流,以及你可以怎样把它做得更好。如果交流有问题,在对他们失望前,寻找方法去提高你自己的实践。 + +我喜欢与非工程师工作。这提供了绝大的机会来学习与传授。你可以经常由实例得到关于你的交流的阐述的指引。工程师被训练于从混乱中梳理秩序,从困惑中得到解释,非工程师会因此喜欢我们。因为我们有技术评审,并且通常可以理解商业话题,我们经常可以发现一个简单的方法来解决问题。 + +很多时候非工程师会出于好意以及一种正确做事情的欲望去规划他们认为会让我们更容易的事情,事实上存在一个仅能通过借助你的技术评审协助外人的观点看到的好得多的方法。我个人喜欢极限编程因为它处理了这种低效,通过与快速评估相结合,使得发现成本与好处最佳结合的方法更加容易。 + +Next [高级技能](../../3-Advanced) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/zh-traditional/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..827ee3a --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,14 @@ +# 如何保持活力 +[//]: # (Version:1.0.0) +创建美丽,有用,聪明的东西的欲望能高度调动程序员的积极性。这是奇妙而令人惊奇的。这种欲望对程序员既不特殊也不普遍,但在程序员中,它是如此强烈而普遍以至于它把程序员与其他角色的人们分割开来。 + +这有一个现实而重要的推论。如果当程序员被要求做一些既不美丽,也没有用,也不漂亮的事情,他们会斗志低落。虽然可以通过做丑陋的,愚蠢的,无聊的东西赚很多的钱,但最后,乐趣才会为公司赚最多的钱。 + +很明显,有一些完全由动机技术组织起来的工业适用这里的情况。这些我可以识别的特定的编程中的事情有: +- 为工作使用最好的语言 +- 寻找机会去使用新技术,新语言,新科技 +- 尝试在每个工程里学习或教授一些东西,即使很小 + +最后,可能的话,估量个人激励的东西对你工作的影响。例如,修复 bug 时,数一数我完全不感兴趣的 bug 的数目,因为这和仍然存在的 bug 数目是独立的,并且这也是影响我对公司的顾客的增值的最小的可能方式。把每个 bug 和一个高兴的顾客关联起来,*是*对我个人的激励。 + +Next [如何被广泛信任](02-How-to-be-Widely-Trusted.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md b/zh-traditional/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md new file mode 100644 index 0000000..14b5240 --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -0,0 +1,7 @@ +# 如何被广泛信任 +[//]: # (Version:1.0.0) +值得信任,才能被信任。你也应该让别人了解你。如果没人了解你,没人会为你投票。跟你亲近的人一起,比如队友,这应该不是一个问题。对你部门或团队以外的人,你通过责任和博知建立信任。有时有人会滥用信任,并要求无理由的赞同。不要害怕,解释因这种赞同会让你必须放弃什么。 + +不要不懂装懂。与队友以外的人一起时,你必须清除地区分“当下在我脑子里不懂的东西”以及“我曾经没有认识到的东西”。 + +Next [如何在时间和空间权衡](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md b/zh-traditional/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md new file mode 100644 index 0000000..6b309ed --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -0,0 +1,15 @@ +# 如何在时间与空间权衡 +[//]: # (Version:1.0.0) +没有上过大学的话,你也可以成为一个好的程序员,但你不知道基本的计算复杂度理论的话,你不可能成为一个好的进阶程序员。你不需要知道‘O’的定义,但我个人认为你应该理解‘常量时间’,‘nlogn’,'n²'的区别。你可能可以不靠这方面的知识,凭直觉知道如何在时间和空间之间权衡,但没有这种知识,你将不会有一个和你同事交流的稳固基础。 + +在设计或理解算法的过程中,算法花费的时间有时候是一个以输入量为自变量的函数。当这种情况发生时,如果运行时间与输入量的对数的 n 倍成正比,我们可以说一个算法的最坏/期望/最好情况运行时间是'nlogn',这个定义和阐述的方式也可以被应用在数据结构占用的空间上。 + +对我来时候,计算复杂度理论是美妙的,并且与物理学一样意义深远,并且可能还有很长的路要走! + +时间(处理器周期)和空间(内存)可以相互交易。工程是关于妥协的,这就是一个好的例子。它并不总是有条理的,然而,编码一些东西时更加紧凑可以节省空间,但要以解码时花费更多的处理时间为代价。你可以通过缓存节省时间,也就是,花费空间去存储某些东西的一个本地副本,但要以维持缓存的一致性为代价。你偶尔可以通过把更多信息放在一个数据结构里来节省时间。这通常只会有较小的空间占用,但可能会使算法复杂化。 + +提高时间空间转换经常把它们中的一个或另一个戏剧性地改变。然而,在你开始做这个工作前,你应该问你自己,你将要优化的是否是最需要优化的?研究算法是有趣的,但你不能让这遮蔽了你的双眼让你看不到这样一个冷酷的事实:优化一些不是问题的问题将不会带来任何明显的区别,但却会造成测试的负担。 + +现代计算机内存越来越便宜,因为不像处理器时间,你在达到边界前你不能看见它,但这种失败是灾难性的。使用内存也有隐藏的代价,比如你影响了其他需要被保留的程序,以及你分配和释放内存的时间。在你想要花更多空间去换取速度之前,请仔细考虑这一点。 + +Next [如何进行压力测试](04-How-to-Stress-Test.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md b/zh-traditional/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md new file mode 100644 index 0000000..888861a --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -0,0 +1,17 @@ +# 如何进行压力测试 +[//]: # (Version:1.0.0) +压力测试很有趣,一开始好像压测的目的是找出系统在负载下能不能工作。现实中,系统在负载下确实能工作,但在负载足够重的某些情况下不能工作。我把这叫做*碰壁*或*撞响*[1]。可能会有例外,但大多数情况下会有这么一堵“墙”。压测的目的是为了指出墙在哪里,然后弄清楚怎么把墙移得更远些。 + +压测计划需要在工程的早期就规划好,因为它经常有助于弄清楚到底什么是被期望的。两秒的网页请求是一个悲伤的失败还是一个了不起的成功?500个并发用户是否足够?这,当然,视情况而定,但一个人在设计系统时就应该知道满足需求的答案。压测需要足够好地为现实建模,使之足够有用。非常容易地模拟500个不稳定并且不可预测的人并行使用系统不是真的可能的,但我们可以至少创造500个模拟(用户),然后尝试模拟他们可能做的部分事情。 + +在压测中,从轻负载开始,然后为系统在一些维度上增加复杂 - 比如输入频率和输入规模 - 直到你抵达那堵墙。如果墙太近了以至于不能满足你的需要,弄明白哪个资源是瓶颈(这通常是那个主要的资源)。它是内存?处理器?I/O?网络带宽?还是数据连接?然后弄明白你可以怎么移动那堵墙。记录下移动墙的那个要素,也就是增加了系统可以处理的负载的那个要素,它可能不能真正在低负载系统下产生危害。但通常重负载下的表现比轻负载下更重要。 + +你必须能够观察几个不同维度,以此来为之构建一个思维模型;单一的技术是不够的。例如,日志经常是给出系统中两个事件间的挂钟时间的好主意。但除非仔细构建,日志不会给出内存使用的可见性甚至是数据结构的大小。相似的,在现代系统里,大量电脑和许多软件系统是合作的。特别是在你碰到那堵墙时(也就是,表现与输入不成线性比例时),这些软件系统可能成为瓶颈。对这些系统的透视力,甚至仅仅对所有参与工作的机器的处理器做测量,都可能是非常有帮助的。 + +意识到墙在哪里的关键不仅是移动这堵墙,而且也是提供对其的预测能力。这样公司可以得到更高效的管理。 + +--- + +[1] "撞响" + +Next [如何在简洁与抽象间平衡](05-How-to-Balance-Brevity-and-Abstraction.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md b/zh-traditional/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md new file mode 100644 index 0000000..183c6e6 --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -0,0 +1,9 @@ +# 如何在简洁与抽象间平衡 +[//]: # (Version:1.0.0) +抽象是编程的关键。你应该仔细选择你需要抽象的程度。充满活力的初学者经常创建许多没有什么用的抽象。一个标识是,你是否创建了这样一个类,不包含任何代码并且没有真的做什么事情,除了抽象一些东西。这种抽象是可以理解的,但代码的简洁性的价值必须与代码的抽象价值相权衡。有时候,我们可以看到一种热情的理想主义者犯的错误:在工程的一开始,定义了一大堆的看起来抽象得很美的类,然后他会推测说它们可以处理每一个可能出现的情况。随着项目推进及琐事掺杂进来,这些代码本身变得混乱了。函数体比他们本来该有的样子还要长。空的类是一种写文档的负担,在压力之下,它们会被忽略。如果让花在抽象上的精力去保持其简短,最后的结果应该会更好。这是一种*推测编程*的形式。我强烈推荐 PAUL gRAHAM[PGSite] 的这篇文章 ['Succinctness is Power' by Paul Graham](http://www.paulgraham.com/power.html)。 + +有这样一种关于*信息封装*和*面向对象编程*的有用技能,但有时候它们被带远了。这些技术让一个人抽象地编码并预计变数。然而,我个人认为,你不应该写太多推测性的代码。例如,在一个对象里用增量器和访问器隐藏一个整数变量是一种可接受的风格,这样变量本身就没有暴露,仅仅暴露了很少的关于它的接口。这确实允许了变量的实现的改变不影响调用代码,并且可能对一个必须提供一个稳定 API 的库编写者是合适的。我不认为这种好处会超过其冗长的代价,特别是当我的团队拥有调用代码并因此可以把调用器重构为比原来的更容易时。四到五行多余的代码会是这种推测性好处的沉重代价。 + +可移植性也有类似的问题。代码是否应当可移植到不同的电脑,编译器,软件系统或平台?还是简单地传输?我认为,不可移植,短而简单传输的代码比长而可移植的代码要好。把不可移植代码限制在特定的领域是一个想对轻松而且无疑是好的主意。比如一个使用了特定 DBMS 的数据库查询的类。 + +Next [如何学习新技能](06-How-to-Learn-New-Skills.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md b/zh-traditional/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md new file mode 100644 index 0000000..b81efbc --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -0,0 +1,13 @@ +# 如何学习新技能 +[//]: # (Version:1.0.0) +学习新技能,尤其是非技术类,是最大的一种乐趣。大多数公司会更加有斗志如果它们明白这对程序员来说是多大的激励。 + +人类通过*做*来学。读书和上课是有用的。但你对一个从不写程序的程序员会有任何敬意吗?学习任何技能,你应该把自己放在一个可以练习技能的宽容的位置。学习一个新的编程语言时,在你必须做一个大工程前,试着用它做一个小的工程。学习管理软件项目时,先试着管理一个小的工程。 + +一个好的导师不是你做事情的替代品,而是比一本书更好的存在。你可以提供什么给一个潜在的导师,作为他的知识的交换?至少,你应该努力学习这样他们的时间才不会被浪费。 + +试着让你的 boss 给你正规的训练,但必须知道,这通常并不会比把相同量的时间花在用你想学的技能来简单玩耍要好上多少。然而,要求训练比在我们不完美世界里的玩耍时间要容易得多,尽管大量正规训练只是在课程上睡觉,等着晚餐聚会。 + +如果你领导团队,需要知道他们是怎么学习的,并且通过给他们安排适量的和他们感兴趣的技能的工程来锻炼他们。不要忘记程序员最重要的技能不是技术。让你的团队成员有一个机会去玩,锻炼勇气,诚实,以及交流。 + +Next [学会打字](07-Learn-to-Type.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/07-Learn-to-Type.md b/zh-traditional/2-Intermediate/Personal-Skills/07-Learn-to-Type.md new file mode 100644 index 0000000..d5e032a --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -0,0 +1,5 @@ +# 学会打字 +[//]: # (Version:1.0.0) +学会盲打。这是一个进阶技能,因为写代码是如此困难以至于你的打字速度是不太相关的,并且不能削减写代码花费的时间,不管你打字有多好。但是,到了你是一个进阶程序员的时候,你可能花费很多时间在用自然语言给你的同事或他人写东西上。这是对你的责任感是一种有趣的测试,学习这样的东西需要专注的时间,但不怎么有趣。有这样一个传说,当 Michael Tiemann 在 MCC 的时候,人们会站在他的门外面倾听他击键的声音,这种声音是如此的急促以至于难以分辨。 + +Next [如何做集成测试](08-How-to-Do-Integration-Testing.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md b/zh-traditional/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md new file mode 100644 index 0000000..b12a93d --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -0,0 +1,7 @@ +# 如何做集成测试 +[//]: # (Version:1.0.0) +集成测试是对已经进行单元测试的各个部分的一种整合测试。集成是昂贵的,并且它出现在测试中。你必须把这个考虑到你的预计和时间表里。 + +理想情况下,你应该这样组织一个项目,使得最后没有一个阶段是必须通过显式集成来进行的。这比在项目过程中,随着事情完成逐渐集成事情要好得多。如果这是不可避免的,请仔细评估。 + +Next [交流语言](09-Communication-Languages.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/09-Communication-Languages.md b/zh-traditional/2-Intermediate/Personal-Skills/09-Communication-Languages.md new file mode 100644 index 0000000..e442315 --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -0,0 +1,11 @@ +# 交流语言 +[//]: # (Version:1.0.0) +在语法系统里,有一些正式定义的,非编程语言但是*交流语言*的语言,它们为促进交流而非标准而特别设计。2003年,最重要的这种语言有: UML, XML, SQL。你应该熟悉这些东西,这样你就可以很好地交流并且决定什么时候去使用它们。 + +UML 是一个丰富的用图表描述设计的正式系统。它的美丽之处在于它既虚拟又正式,在作者和观众都了解 UML 的前提下,可以容纳大量的信息。你需要了解它,因为设计有时候就是用这种方式交流的。有一些非常有用的工具可以让制作 UML 图看起来非常专业。在很多情况下,UML 太正式了,我自己会使用更简单的*箱子与箭头*的风格来设计图标。但我非常确定 UML 对你来说至少跟学习拉丁语一样有用(译者注:国外拉丁语使用很广泛)。 + +XML 是设计新标准的标准。这不是一个数据间交换的问题的解决方案,尽管你有时候会看到它在这种情况下出现。更进一步,它是一种受欢迎的对大部分数据交换的无聊部分的自动化,也就是,把表现结构化为线性序列,还有将其转回一个结构。它提供了一些漂亮的类型和正确性检查,尽管,又一次,实践中你可能需要的只是其中的一部分。 + +SQL 是一种非常有力而丰富的数据查询和操作语言,而非一种编程语言。它有许多种类,典型地依赖于产品,但这没有标准核心那么重要。SQL 是关系数据库的*巧舌弗兰卡*。你可能可以也可能不可以在任何领域从对关系数据库的理解中受益,但你必须对它们和 SQL 的语法和含义有基本的理解。 + +Next [重型工具](10-Heavy-Tools.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/10-Heavy-Tools.md b/zh-traditional/2-Intermediate/Personal-Skills/10-Heavy-Tools.md new file mode 100644 index 0000000..3843661 --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -0,0 +1,14 @@ +# 重型工具 +[//]: # (Version:1.0.0) +随着我们的科技文化的进步,软件技术从不可想象,到研究,到新的产品,到标准化产品,到广泛可用和廉价产品。这些重型工具可以拉动很大的负载,但可能是进阶的,并且需要花大量投资去理解。进阶程序员必须知道如何管理它们以及它们什么时候应该被使用或考虑。 + +现在在我看来,一些最好的重型工具是: + +- 关系数据库; +- 全文搜索引擎; +- 数学库; +- OpenGL; +- XML 解析器; +- 电子表格。 + +Next [如何分析数据](11-How-to-analyze-data.md) diff --git a/zh-traditional/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md b/zh-traditional/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md new file mode 100644 index 0000000..2f970d8 --- /dev/null +++ b/zh-traditional/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -0,0 +1,17 @@ +# 如何分析数据 +[//]: # (Version:1.0.0) +当你检查一个商业活动并且发现了把它转换为软件应用程序的需求时,数据分析是软件开发早期的一个过程。这是一个官方的定义,当你,一个程序员,应该集中注意力在写别人设计的东西的代码时,这可能会让你相信数据分析是一种更应该归入系统分析的行为。如果我们严格遵循软件工程范式,这可能是正确的。有经验的程序员会成为设计者,最尖锐的设计者变成商业分析师,因此被冠名去思考所有数据需要,并且给你充分定义的任务去执行。这不完全是对的,因为数据是每种编程活动的核心。不管你在你的程序里做什么,你不是在移动数据就是在修改数据。商业分析师分析的是更大尺度上的需要,软件设计者更加压榨这个比例以至于,当问题在你的桌上落地时,好像你需要做的所有事情是应用聪明的算法,开始移动已经存在的数据。 + +不是这样的。 + +不管你开始观察它的是哪个阶段,数据是一个良好设计的应用程序主要考虑的因素,如果你仔细观察一个数据分析师是怎么从客户请求中获取需求的,你会意识到,数据扮演了一个基本的角色。分析师创建了所谓的数据流表,所有的数据源被标记出来,信息的流动被塑造出来。清晰定义了什么数据应该是系统的一部分,设计师将会用数据关系,数据交换协议,文件格式的形式塑造数据源,这样任务就准备好传递给程序员了。然而,这个过程还没结束,因为你(程序员)在这个周密的数据提取过程后,需要分析数据以用最好的可能方式表现任务。你的任务的底线是 Niklaus Wirth,多种语言之父,的金句:“算法+数据结构=程序”。这永远不是一个独立的自嗨的算法。每个算法都至少被设计去做一些至少与一段数据相关的事情。 + +因此,由于算法不会在真空中滚动轮子,你需要分析其他人已经为你标记好的数据和必须写入代码的必要的数据。 +一个小例子会使得事情更清楚。实现一个图书馆的搜索程序时,通过你的说明书,用户用类型/作者标题/出版社/出版年份/页数来选择书本。你的程序的中级目标是提供一个合法的 SQL 语句去搜索后端数据库。基于这些需要,你有几个选择:按顺序检查每个控制条件,使用一个 switch 语句,或者几个 if 语句;用一个数据控制数组,把它们与一个事件驱动引擎相连。 + +如果你的需求也包括提高查询性能,通过确认每个项在一个特殊顺序里,你可能考虑使用组件树去构建你的 SQL 语句。正如你可以看到的,算法的选择依赖于你决定使用或将要创建的数据。这样的决定产生高效算法和糟糕算法间的区别。 +然而,效率不是唯一要考虑的因素。你可能在你的代码里使用一打命名变量,让它变得尽可能高效。但这样一段代码可能不能容易地维护。可能为你的变量选择一种合适的容器可以保持相同的速度,此外,在的你同事明年看代码的时候,让他们能够更好地理解代码。更多的,选择一个良好设计的数据结构可能允许他们在不重写代码的前提下,拓展你的代码的功能。长久看来,你对数据的选择决定了你结束代码的工作后,它能工作多久。 + +让我给你看另一个例子,只是一些思想粮食,让我们假设你的任务是找到字典里超过三位的同字异构词(一个异构词必须在同样的字典里有另一个词)。如果你把这当做一个计算任务,你将会结束于无尽的,尝试找出每个单词的所有组合,然后拿它跟列表里的所有其他单词比较,这样一个无尽的努力中。然而,如果你分析了手头的数据,你会意识到,每个单词可能被一个包含这个词本身以及用它的字母作为 ID 的排序数组的记录所代表,这个蛮力算法可能需要运行几天,而小的那个算法只是一件几秒的事。下次面对一个棘手的问题时,记住这个例子。 + +Next [团队技能 - 如何管理开发时间](../Team-Skills/01-How-to-Manage-Development-Time.md) diff --git a/zh-traditional/2-Intermediate/README.md b/zh-traditional/2-Intermediate/README.md new file mode 100644 index 0000000..32ad0d6 --- /dev/null +++ b/zh-traditional/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. 进阶 +[//]: # (Version:1.0.0) +- 个人技能 + - [如何保持活力](Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被广泛信任](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在时间和空间之间该如何权衡](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何进行压力测试](Personal-Skills/04-How-to-Stress-Test.md) + - [如何权衡简洁与抽象](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何学习新技能](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [学会打字](Personal-Skills/07-Learn-to-Type.md) + - [如何进行集成测试](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流语言](Personal-Skills/09-Communication-Languages.md) + - [重型工具](Personal-Skills/10-Heavy-Tools.md) + - [如何分析数据](Personal-Skills/11-How-to-analyze-data.md) +- 团队技能 + - [如何管理开发时间](Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方软件风险](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理咨询](Team-Skills/03-How-to-Manage-Consultants.md) + - [如何适度交流](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言异议以及如何避免](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- 评判 + - [如何权衡开发质量与开发时间](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理软件系统依赖](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何评判软件是否太不成熟了](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何决定购买还是构建](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何专业地成长](Judgment/05-How-to-Grow-Professionally.md) + - [如何评估面试者](Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何决定什么时候使用奇妙的计算机科学](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何与非工程师交谈](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/zh-traditional/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md b/zh-traditional/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md new file mode 100644 index 0000000..66d67d9 --- /dev/null +++ b/zh-traditional/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -0,0 +1,11 @@ +# 如何管理开发时间 +[//]: # (Version:1.0.0) +管理开发时间,需要维护一个简明且实时更新的计划。一个工程计划是一个估计,一个时间表,一系列取得进步的里程碑,还有对你的团队或者你的时间在每个任务的估计和安排。这也应该包括你需要记得去做的其他事,比如与质量保障人员见面,准备文档,或者订购设备。如果你在一个团队里,工程计划会是一个共同承认的协议,不论是在开始,还是进行的过程中。 + +工程计划存在的意义是帮助做出决定,而非展示你是如何组织的。如果一个工程计划太长或者不是最新的,它对做出决定将是无用的。现实中,这些决定通常是关于独立的个人的。计划和你的判断让你决定你是否应当把任务从一个人身上移到另一个人身上。里程碑标识了你的进展。如果你有一个奇妙的工程规划工具,不要被为工程创建一个表面巨大设计(Big Design Up Front)所迷惑,但可以用它保持清晰和实时性。 + +如果你没有一个里程碑,你应该采取即时的行动,比如通知你的 boss 工程已经滑过的部分中进度的完成。这种估计和时间表可能不会在开始时很完美,这会产生这样一种幻觉,你能够填补工程的上一个部分中错过的日志。你可以。但这很可能是因为你低估了那个部分或者高估了一部分。所以工程进度的完成已经滑过了,不管你是否喜欢。 + +确保你的计划包括了:内部团队会议,写代码,文档,规划周期活动,集成测试,处理外部关系,疾病,休假,已有工程维护,还有开发环境维护。工程计划可以作为一种为局外人或你的 boss 准备的关于你或你的团队正在做的事情的视图。因为如此,所以它应该是短且及时更新的。 + +Next [如何管理第三方软件危机](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/zh-traditional/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md b/zh-traditional/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md new file mode 100644 index 0000000..2518db2 --- /dev/null +++ b/zh-traditional/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -0,0 +1,11 @@ +# 如何管理第三方软件危机 +[//]: # (Version:1.0.0) +一个工程通常依赖于其不能控制的组织所生产的软件,第三方软件危机是每个相关的人都必须意识到的。 + +永远也不要把希望放在*蒸汽*上面。蒸汽是任何所谓的尚未可用然而声称可用的软件。这是最确定的一种破产的方式。仅仅怀疑一个软件公司在某个日期对于某个软件产品的某个特性的承诺是不明智的。更明智的做法是完全忽略它,并且忘记你曾听说过这种事。不要在你的公司使用的任何文档里写下这些东西。 + +如果一个第三方软件不是蒸汽,它仍然是有风险的,但至少它是一个可以处理的蒸汽。如果你正在考虑使用第三方软件, 你应该早点投入一点精力去评估它。人们可能没听说过,评估三个产品的适合性要花两个星期还是两个月,但这必须尽可能及早做。如果没有合适的评估,集成的代价就不能被准确计算。 + +理解已有的为某个特殊目的的第三方软件的适用性是非常见仁见智的东西。这是非常客观的,并且通常住在专家心里。如果你发现了那些专家,你可以节省很多时间。很多时候,一个工程会如此完全地依赖于第三方软件,以至于如果集成失败了,工程就失败了。像时间表里写的那样清晰地表达了危机。如果危机不能被尽早消除,试着订一个为意外准备的计划,比如可用的第二方案,或者自己写下功能点的能力。永远不要让时间表依赖于蒸汽。 + +Next [如何管理咨询师](03-How-to-Manage-Consultants.md) diff --git a/zh-traditional/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/zh-traditional/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..bd58e19 --- /dev/null +++ b/zh-traditional/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,9 @@ +# 如何管理咨询师 +[//]: # (Version:1.0.0) +使用咨询师,但不要依赖他们。他们是神奇的人,非常值得尊敬。因为他们看过许多不同的工程,他们通常比你知道更多具体技术,甚至是编程技术。最好的使用他们的方式是像家教那样用例子教学。 + +然而,他们通常不能像正常员工那样用相同的感觉融入团队,可能仅仅是因为你没有足够的时间去学习他们的优点和缺点。他们的工资更低。他们更容易离开。如果公司做得好,他们可能得到的更少。有些可能是好的,有些可能与平均水平一致,有些可能挺糟糕,但希望你对咨询师的选择不会像你对雇员的选择那样仔细,这样你会获得更多不好的咨询师。 + +如果咨询师要写代码,你必须在你使用它们前仔细 review。有着大段带风险而没有被 review 的代码,会让你完成不了工程。事实上这对所有的团队成员都是成立的,但你通常有更多与你接近的团队成员的知识。 + +Next [如何适量交流](04-How-to-Communicate-the-Right-Amount.md) diff --git a/zh-traditional/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md b/zh-traditional/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md new file mode 100644 index 0000000..9141eed --- /dev/null +++ b/zh-traditional/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -0,0 +1,7 @@ +# 如何适量交流 +[//]: # (Version:1.0.0) +仔细考虑会议的代价:这花费了*随参与者数量倍增的时间*。会议有时候是必要的,但越小越好。小会议的交流质量更好,过度浪费的时间更少。如果一个人在会议感到厌烦,把这当做会议应该更小的标识。 + +非正式交流值得做任何事情去鼓励。更多有用的沟通工作在同事间的午饭可以进行,而非其他的时间。许多公司没有意识到或者不支持这一点,这是一种遗憾。 + +Next [如何直言异议以及如何避免](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/zh-traditional/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md b/zh-traditional/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md new file mode 100644 index 0000000..11a2e85 --- /dev/null +++ b/zh-traditional/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -0,0 +1,11 @@ +# 如何直言异议以及如何避免 +[//]: # (Version:1.0.0) +异议是一个做出好决定的绝佳机会,但这需要被谨慎处理。你可能会觉得你充分的表达了你的想法,并且在决定做出前,你的意见已经被听取。这种情况下,没有什么可以再说的,你应该决定你是否要支持这个决定,即使你不同意它。如果你可以在自己不同意的情况下,支持这个决定,就这样说实话。这展示了你是多么有价值,因为你是独立的,不是一个唯唯诺诺之人,同时是一个尊重决定的团队成员。 + +有时候一个你不同意的决定,会在决策者没有充分听取你的观点前做出。你应该在公司和集体的基础上评估是否应该提出这个话题。如果在你看来这只是一个小错误,这可能不值得重新考虑。如果在你看来这是一个大错,你当然必须提出异议。 + +通常,这不是一个问题。在一些充满压力的环境下,在一些个人因素下,这会导致事情个人化。例如,一些非常牛逼的程序员缺乏在有好的理由认为一件东西是错的情况下去挑战决议的信心。在最糟的情况下,决策者是不可靠的,并会把这变成一个对权威的挑战。最好记住,这种情况下,人们会用他们大脑中爬虫动物的部分来做出反应。你应该私下提出你的争议,然后尝试展示新的知识是如何改变决议做出的基础的。 + +不管决议是否被推翻,你必须记住你永远不能说出“我的话撂这了,我早就这样告诉你了”这样的话,因为这个决定已经得到了充分探讨。 + +Next [判断 - 如何在开发质量和开发时间间权衡](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/zh-traditional/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md b/zh-traditional/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md new file mode 100644 index 0000000..6fe2a41 --- /dev/null +++ b/zh-traditional/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -0,0 +1,11 @@ +# 如何与时间压力做斗争 +[//]: # (Version:1.0.0) +发布压力是快速推出好产品的压力。这是好的,因为它反映了市场事实,并且在某个意义上是健康的。时间压力是迫使一个产品更快地推出的压力,这是浪费的,不健康的,并且太普遍了。 + +时间压力的存在是有原因的。给程序员任务的人们没有完全尊重我们的强烈的工作道德以及作为一个程序员的乐趣。可能是因为他们把自己的习惯投射到我们身上,他们相信,要求更快会让我们更加努力工作,使得工程更快完成。这可能确实是对的,但效果很小,损害很大。另外,他们看不到生产软件真实需要的东西。他们看不到,也不能够自己创造,他们能做的唯一事情就是看着发布的压力,然后烦程序员。 + +与时间压力斗争的方法是简单地把它当做发布压力,实现的方法是让可用劳力与产品间的关系变得透明。提供一个诚实,细致,大部分可理解的对所有相关劳力的估计,是一种最好的实现方式。允许做出好的管理决定以权衡可能的功能也是一个附加的好处。 + +必须清楚解释的关键是,预算是一种几乎不可压缩的液体。就像你不能把水放进充满的瓶子里,你不能往充满的时间中填入更多任务。某种意义上,程序员永远不会拒绝,但更喜欢说“得到你想要的东西,你会失去什么?”,做出清晰的预算的效果将会是增加对程序员的尊敬。这也是其专业行为的一种表现。程序员的努力工作会被看到。很明显,设置一个不现实的时间表对每个人都是痛苦的。程序员不能被欺骗。要求他们做一些不现实的东西是对他们的不尊重和不道德。极限编程放大了这个问题,并且围绕它构建了一套流程,我希望每个读者能足够幸运去使用它。 + +Next [如何理解用户](02-How-to-Understand-the-User.md) diff --git a/zh-traditional/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md b/zh-traditional/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md new file mode 100644 index 0000000..d2c7b33 --- /dev/null +++ b/zh-traditional/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -0,0 +1,17 @@ +# 如何理解用户 +[//]: # (Version:1.0.0) +理解用户以及帮助你的 boss 理解用户是你的责任。因为用户没有像你一样密切地与你的产品的制造产生联系,他们的表现有点不同: + +- 用户通常会做出简短的判断 +- 用户有他们自己的工作,他们主要会思考你的产品中小的改进,而非大的改进 +- 用户看不到你的产品的整个用户画像 + +你的责任是找出他们真实需要的东西,而非他们说他们需要的东西,然而,更好的是在你开始前给他们提出建议,并且让他们认同你的建议就是他们想要的,但他们也可能没有做这种事的愿景。你对你自己的主意的信心是要看情况的。你必须同时与自大和错误的谦逊做斗争去找出什么是人们真实想要的。这两种人,或者同一个人身上两种思维模式,一同和谐工作会给出最好的机会来给出正确的愿景。 + +你在用户身上花费的时间越多,你就越能更好地理解什么能够真正地成功。你应当尝试在你的用户上尽可能测试你的想法,如果可能的话,你甚至应当和他们一起吃饭。 + +Guy Kawasaki [Rules] 强调过在倾听之外,*观察*你的用户的重要性。 + +我相信,合伙人和咨询师让客户说出他们内心真正想要的东西有巨大的困难。如果你想成为一个咨询师,建议你基于用户清晰的头脑以及他们的钱包来选择客户。 + +Next [如何得到晋升](03-How-to-Get-a-Promotion.md) diff --git a/zh-traditional/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md b/zh-traditional/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md new file mode 100644 index 0000000..5c73172 --- /dev/null +++ b/zh-traditional/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -0,0 +1,13 @@ +# 如何获得晋升 +[//]: # (Version:1.0.0) +想要被提升为某种角色,先做那个角色该做的事情。 + +为了提升到某个位置,找到那个位置期望做的事情,然后去做。 + +想要得到薪酬的提升,带着信息去协商。 + +如果你觉得你值得得到提升,与你的 boss 聊一聊。清楚地问他们你需要做什么才能获得提升,然后努力去做。这听起来很老套,但大多数时候你对你需要做的事情的追求与你 boss 的想法是不同的。这可能会让你的 boss 在某些程度上有些失落。 + +大多数程序员可能在某些形式上对他们的相对能力有夸张的感觉 --- 毕竟,我们不可能都在前10%里!然而,我也见过一些非常不得志的人。人不能期望每个人的评价在什么时候都完美与现实相同,但我认为人们通常在一定程度上是公平的,有这样一个警告:如果别人看不到你的工作,你就得不到欣赏。有时候,因为偶然或个人习惯,有些人可能得不到太多关注。在家努力工作或者与你的团队和 boss 地理隔离的话,这会变得特别困难。 + +Next [服务你的团队 - 如何发展才能](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/zh-traditional/3-Advanced/README.md b/zh-traditional/3-Advanced/README.md new file mode 100644 index 0000000..bc276e8 --- /dev/null +++ b/zh-traditional/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. 高级 +[//]: # (Version:1.0.0) +- 技术评判 + - [如何从不可能中找到困难的部分](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型语言](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [选择语言](Technical-Judgment/03-Choosing-Languages.md) +- 机智地妥协 + - [如何与时间压力作斗争](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用户](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何获得晋升](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- 服务你的团队 + - [如何发展才能](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何选择工作内容](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何让你队友的价值最大化](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何划分问题](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何处理无聊的问题](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何为工程获取支持](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何发展一个系统](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地沟通](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告诉人们他们不想听的东西](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何处理管理神话](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何处理混乱的组织](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md b/zh-traditional/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md new file mode 100644 index 0000000..0812f3a --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -0,0 +1,23 @@ +# 如何发展才能 +[//]: # (Version:1.0.0) +Nietschze 夸大了他所说的: + +>那些无法摧毁我的,只会让我更强大 + +你最大的责任是对你的团队负责。你应该非常了解他们中的每个人。你应该激励你的团队,但不要让他们过劳。你通常应该告诉他们他们被激励的方式。如果他们觉得划算,他们会被很好的激励。每个工程中,或者在每个其他的工程里,试着同时用他们建议的以及你认为对他们好的方式去激励他们。激励他们的方法不是给他们更多工作,而是给他们一个新的技能或在团队里扮演一个新的角色。 + +你应该允许人们(包括你自己)偶尔失败,并且应该为一些失败预留一些时间。如果从未有失败,冒险也就没有意义。如果没有偶然的失败,说明其实你没有足够努力。当一个人失败了,你应该尽可能温柔地对待他,但不该把他们像成功了那样对待。 + +为了让每个团队成员被充分激励,问清楚他们中的每个人,如果他们没有动力的话,他们需要什么才能被充分激励。你可能需要让他们保持不满意的状态,但你需要知道每个人需要的是什么。 + +你不能放弃因为低落的情绪或者不满就故意不承担工作的那些人,然后就让他们这样懒散下去。你必须试着让他们充分被激励并且有效率。只要你有耐心,坚持这样做。当你的耐心耗尽时,就解雇他们吧。你不能允许故意不司其职的员工留在团队里,因为这对团队不公平。 + +通过在公众场合这样说,让你团队中的强大成员清楚地知道他们是强大的。表扬应当公开,批评应当私密。 + +团队中的强大成员会自然地比弱的成员有更多困难的任务。这是完美而自然的,没人会因此困扰,因为每个人都在努力工作。 + +一个在工资中没有反馈出来的奇怪的事实是,好的程序员比十个糟糕的程序员要有效率得多。这导致了一种奇怪的现象。通常,如果你们的弱程序员不挡道的话,你能跑的更快。如果你这样做了,事实上你在短期能取得更多进度。然而, 你的交易会失去一些重要的好处,叫做对弱小成员的训练,对集体知识的传递,失去强大程序员后的恢复能力。强大的程序员对这种现象应该温和些,并且从各种角度去考虑这个问题。 + +你可以经常给强大的团队成员有挑战的,但细致描绘的任务。 + +Next [如何选择工作的内容](02-How-to-Choose-What-to-Work-On.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md b/zh-traditional/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md new file mode 100644 index 0000000..0fa3e6e --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -0,0 +1,5 @@ +# 如何选择工作的内容 +[//]: # (Version:1.0.0) +你需要在你个人的需要和团队的需要间权衡,选择需要做工程中的哪个部分。你应该做你最擅长的东西,但是也要试着去找一种方式来激励自己,不是通过承担更多的工作而是通过练习新的技能。领导才能和交流能力比技术能力更重要。如果你非常强大,承担最困难或最有风险的任务,在工程中尽可能早地完成这部分,以此减少风险。 + +Next [如何让你队友的价值最大化](03-How-to-Get-the-Most-From-Your-Teammates.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md b/zh-traditional/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md new file mode 100644 index 0000000..848b62f --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -0,0 +1,15 @@ +# 如何让你队友的价值最大化 +[//]: # (Version:1.0.0) +为了让你的队友的价值最大化,发展好的团队精神,试着保持每个人的个人挑战与渴望。 + +为了发展团队精神,文化衫与聚会是有益的,但不如对个人的尊重。如果每个人尊重其他的每个人,就没有人会让其他人失望。团队精神产生于人们为团队做出牺牲,优先思考团队的利益而非自己利益的时候。作为一个领导者,在这个方面,没有付出就没有收获。 + +团队领导力的一个关键是促进团结,这样每个人都会听你的。有时候这意味着允许你的队友犯错。也就是,基于这种团结,如果对项目没有太大的损害,你必须允许你团队的一部分成员用他们自己的方式做事,即使你有很大的信心认为这是一件错事。当这种情况确实发生时,不要同意他们的观点,简单公开地反对之,然后接受这种团结。不要让人觉得你受伤了,或者认为你是被迫的,简单地陈述你不同意,但认为团队的团结是更加重要的。这经常会导致他们反悔。如果他们真的反悔了,不要坚持他们一开始的计划。 + +如果在你们从所有合适的角度讨论了这个话题后,有个人会反对,简单地告诉他们,你必须做一个决定,并且这就是你的决定。如果有方法去评估你的决定是否是错的,或者它稍后是否是错的,尽可能快速切换,并感激那个对的人。 + +询问你的团队,包括集体与个人这样一个问题:他们认为什么能创造团队精神以及创造一个高效的团队。 + +经常表扬,但不要浪费。尤其是表扬那些反对你且确实值得表扬的人。公开表扬,私下批评。但有这样一种例外:有时候进步或者纠正一个错误但却没有注意到错误的根源,是不能被表扬的,这种进步应该私下表扬。 + +Next [如何划分问题](04-How-to-Divide-Problems-Up.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md b/zh-traditional/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md new file mode 100644 index 0000000..86f6ed4 --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -0,0 +1,9 @@ +# 如何划分问题 +[//]: # (Version:1.0.0) +接手一个软件工程并把它分为可以由个人实现的任务是很有趣的。这事应该及早进行。有时候经理可能会认为不考虑个人的项目能够起作用。这是不可能的,因为每个人的生产力是如此广泛地不同。对某个组件有特殊知识的人也经常改变,并且可以对工作效果有一个数量级的影响。 + +正如一个作曲家对其演奏乐器的音色的考虑,或者运动队教练对每个运动员的体能的考虑那样,有经验的团队领导,通常不能够把工程依据团队成员需要承担的角色那样划分成一个个的任务。这是好的团队不容易解散的一个原因。 + +因此有这样一种危险:人们在锻炼自己的能力时会感到无聊,并且不会提高他们的弱项或者学习新技能的能力。然而,如果不被过度使用的话,精通是一个非常有用的生产工具。 + +Next [如何处理无聊的任务](05-How-to-Handle-Boring-Tasks.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md b/zh-traditional/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md new file mode 100644 index 0000000..bde52fd --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -0,0 +1,7 @@ +# 如何处理无聊的任务 +[//]: # (Version:1.0.0) +有时候避免对公司或工程的成功至关重要却很无聊的任务是不可能的。这些任务可能真的会降低那些必须执行它们的人的斗志。最好的处理方法是使用或者发扬 Larry Wall 的程序员懒惰美德。试着找一些方法让计算机去做这个任务,或者帮助你的队友去做这个。用一个程序花一个星期去完成要手动去用一个星期完成的任务能让你懂得更多,并且有时候这是可重用的。 + +如果所有其他的途径都不能工作,为那些必须做这个无聊任务的人道歉,但无论什么情况,不要让他们去单独完成它。至少安排一个两人团队去做这个事情,并增强健康的团队协作来完成这个任务。 + +Next [如何为工程获取支持](06-How-to-Gather-Support-for-a-Project.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md b/zh-traditional/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md new file mode 100644 index 0000000..adc8cac --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -0,0 +1,5 @@ +# 如何为工程获取支持 +[//]: # (Version:1.0.0) +要给工程获取支持,需要创建并交流一个能够证明这个组织整体的真正价值的愿景。试着让其他人分享他们对你所创造的愿景的观点。这给他们一个理由去支持你并给予你他们的观点所带来的价值。独立地为你的工程补充关键的支持者。不论在什么可能的地方,展示,但不告诉。如果可能的话,构建一个原型或者一个模型来证明你的主意。一个原型总是有力的,但在软件中,它比任何书面的描述都要高级得多。 + +Next [如何发展一个系统](07-How-to-Grow-a-System.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md b/zh-traditional/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md new file mode 100644 index 0000000..c6e06b1 --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -0,0 +1,23 @@ +# 如何发展一个系统 +[//]: # (Version:1.0.0) +树的种子包含了成长的思想,但不完全实现成长体的形式与力量。胚胎会成长。它会变大。它看起来更像成长体,并越来越有用。最终它孕育果实。最后,它死亡并且它的躯体喂养了其他的有机体。 + +对待软件我们也应当有这样的荣耀。一架桥不是这样的,永远不会有一架婴儿桥,但只是有一座未完成的桥。桥比软件要简单得多。 + +认识到软件的成长是有益的,因为这允许我们在有一个完美的思维图景前取得有用的进步。我们可以从用户那里获得反馈,并用之纠正这种成长。修剪掉疲软的四肢才能健康。 + +程序员必须设计一个完成的可分发可使用的系统。但高级程序员需要做的更多。你必须设计一个终止于完结系统的成长路线。你的工作是,得到一个想法的萌芽,然后把它尽可能顺利地变成一个有用的人工制品。 + +因此,你必须模拟最终的结果,用一种工程团队可以为之雀跃的方式去交流。但你也必须和他们交流一条非跳跃式的路径,从他们所知到他们想要成为的地方去。在整个过程中,这棵树必须活着,它不能在什么时候死去,然后又复活过来。 + +这条路径会是螺旋发展的。里程碑之间永远不会太远,这对于在路上取得进步是有用的。在极端的商业环境里,如果里程碑可以实现并尽早赚钱是最好的。即使他们离良好设计的端点还有很远。程序员的一个工作就是通过理智的选择用里程碑表示的成长路径来平衡即时的报酬与将来的报酬。 + +高级程序员对软件,团队,个人的成长有集体责任。 + +一个读者,Rob Hafernik,在这一节中写下了这样的评论: + +> 我认为你过低强调了这里的重要性。不仅是系统,还有算法,用户界面,数据模型,等等。因为你工作在一个庞大的系统中,必须有即时目标相关的可测量的进步,所以这些也是*至关重要的*。没有什么比抵达终点却发现一切都不能工作更加恐怖(看看最近的投票新闻系统的崩溃吧)。我甚至想进一步把这当做自然的法则:没有庞大,复杂的系统可以由碎片实现,这只能由一个简单的系统循序渐进成长为一个复杂的系统。 + +对此,我们只能回答,*要有光*! + +Next [如何有效地沟通](08-How-to-Communicate-Well.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md b/zh-traditional/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md new file mode 100644 index 0000000..08d6c6c --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -0,0 +1,11 @@ +# 如何有效地沟通 +[//]: # (Version:1.0.0) +为了良好地沟通,你必须认识到它的困难。它本身就是一种技能。与你交流的人本身是有瑕疵的,这一事实使得沟通变得更加困难。他们不会努力去理解你。他们不善言辞。他们经常过度工作或者无聊,至少,有时候只关注他们自己的工作而非你要发表的长篇大论。上课,练习写作,公共演讲,聆听,这些东西的一个好处是,如果你擅长它们,你可以更容易看到问题所在以及解决方法。 + +程序员是一种依赖于与团队交流而生存的社会动物。高级程序员是一种依赖于与团队外的人交流而满意的社会动物。 + +程序员从混沌中带来秩序,一种实现这一目标的有趣方法是从外部的一个提议开始。这能用*稻草人*或*白纸*模式或者口头的方式来完成。这种领导对于让团队置身于辩论中有极大的好处。这也把你暴露到批评,或者拒绝与否定中。高级程序员必须准备好接受这些,因为他有特殊的能力,也因此有特殊的责任。非程序员出身的企业家需要程序员在某些方面提供领导。程序员是思想与现实之间的一部分桥梁。 + +我没有很好地掌握沟通的技巧,但我正在尝试的是一种四叉路径:在我有了一些有序的主意并且充分准备好后,我试着口头表达,交给人们一张白纸(可能是真实的纸,也可能是电子的)来给他们展示一个 demo,然后耐心地重复这个过程。很多次我想过,我们在这种困难的沟通里还是不够耐心。如果你的想法没有马上被接受,你不应该丧气。如果你在准备中投入了精力,没有人会因此看低你。 + +Next [如何告诉人们他们不想听的东西](09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md b/zh-traditional/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md new file mode 100644 index 0000000..fa4f1b7 --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -0,0 +1,9 @@ +# 如何告诉人们他们不想听的东西 +[//]: # (Version:1.0.0) +你会经常需要告诉人们一些让他们不舒服的事情。记住,你必须为某种原因才这样做。即使没有什么可以用来解决这个问题,你也该尽早告诉他们,这样他们才能充分警觉。 + +向别人指出一个问题的最好方法是同时提供一个解决方案。其次的方法是呼吁他们寻求帮助。如果你有不被信任的危险,你应该为你的主张寻求支持。 + +一种你必须说的最不舒服且普遍的事情是“时间不够”。尽责的程序员讨厌这样说,但必须尽早说。没有什么比 deadline 抵达,不得不推迟进度更加糟糕,即使唯一的行动是通知每个人。更好的做法是,作为一个团队整体来做这件事,如果物理上做不到,至少是精神上这样做。你会想要得到你的团队对你的观点以及你为之所做的事情的支持,团队必须与你共同面对这样的后果。 + +Next [如何处理管理神话](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md b/zh-traditional/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md new file mode 100644 index 0000000..3d18a0e --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -0,0 +1,12 @@ +# 如何处理管理神话 +[//]: # (Version:1.0.0) +*神话*这个词有时候意味着虚构。但这有着更深层的内涵。它也意味着一些解释宇宙以及和人类和宇宙之间的关系的宗教故事。管理者倾向于忘记他们作为一个程序员时学到的东西,并且相信某种传说。试着让他们相信这种传说是错的,正如让一个虔诚的宗教信徒从他们的信仰中醒悟过来一样粗鲁而失败。因此,你应该认可这些信仰: + +- 文档越多越好。(他们需要文档,但他们不会想要你在这些东西上花时间。) +- 程序员是平等的。(程序员可以按重要程度分类。) +- 分配更多资源给迟来的项目可以让它加速。(与新人的交流的代价大多数时候很繁重并且无用。) +- 程序员的效率可以用一些简单的标准尺度来度量,比如代码行数(如果简洁才是力量,那么代码行数是坏的,而非好的。) + +如果有机会,你可以试着解释这些东西,但如果你没有成功,不要觉得悲伤,不要好斗地反对这些神话以致损害了你的声望。每个这样的神话增强了管理者关于他们有一些对正在进行的事情的实际控制的想法。真相是,如果管理者是好的,他们会帮助你,如果他们是坏的,他们会妨碍你。 + +Next [如何处理组织混乱](11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/zh-traditional/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md b/zh-traditional/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md new file mode 100644 index 0000000..b7236df --- /dev/null +++ b/zh-traditional/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md @@ -0,0 +1,11 @@ +# 如何处理组织混乱 +[//]: # (Version:1.0.0) +经常会有短暂的组织混乱,比如解雇,收购,IPO,新雇佣,等等。对每个人来说这都是令人不安的,但可能对于那些将自尊建立在能力而非位置上的程序员来讲,这种不安不会那么严重。组织混乱对程序员来讲是锻炼他们的魔力的好机会。因为这是一个集体秘密,在最后我会有所保留。如果你不是一个程序员,就不要再读下去了。 + +> 工程师有能力去创造与维持。 + +非工程师可以安排人们,但,在典型的软件公司,如果没有程序员的话,他们不能创造与维持任何东西,正如工程师通常不能有效地销售产品或者管理商业。这种力量对于大多数与临时组织混乱相关的问题是一种抵抗。如果你有这种力量,你应当完全忽视这种混乱并当做什么都没发生那样坚持下去。你可能,当然,被解雇,但如果这发生了,你可能因为这种力量得到新的工作。更普遍的,一些紧张的没有这种魔力的人会进入你的空间并告诉你做一些蠢事。如果你真的确信这是一件蠢事,最好的做法是微笑,点头,直到他们走开,然后继续做你认为对公司最好的事情。 + +如果你是一个领导者,告诉你的员工做一样的事情,告诉他们忽视其他任何人告诉他们的东西。这种行为的过程对你个人是最好的,对你的公司或工程也是最好的。 + +Next [词汇表](../../4-Glossary.md) diff --git a/zh-traditional/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/zh-traditional/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..494edab --- /dev/null +++ b/zh-traditional/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# 如何从不可能中找到困难的部分 +[//]: # (Version:1.0.0) +解决困难,识别不可能是我们的工作。大多数职业程序员认为,如果有些问题不能从一个简单系统发展而来,或者不能评估,那它就是不可能实现的。然而,根据这个定义,研究本身就是不可能的。大量的工作是困难的,但不是必然不可能的。 + +这种区别是滑稽的,因为你可能经常被要求做一些事实上不可能的事情,不论是从科学观点还是从软件工程观点。然后你的工作就变成了帮助老板找到一个合理的,仅仅是困难而非不可能的解决方案,去满足他们大部分的需要。当一个解决方案可以被自信地规划且风险可以预料时,它只是困难而已。 + +砍掉模糊的需求是不可能的,比如“构建一个系统为任何人计算最受欢迎的发型和颜色”。如果需求可以做得更加细致,它就经常会变成仅仅是困难,比如“构建一个系统去计算某个人的发型和颜色,允许他们预览与做出改变,让顾客在原始风格的基础上满意度变大,这样我们就可以赚很多钱”。如果没有关于成功的清晰定义,你就不会成功。 + +Next [如何使用嵌入型语言](02-How-to-Utilize-Embedded-Languages.md) diff --git a/zh-traditional/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md b/zh-traditional/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md new file mode 100644 index 0000000..8f7f7b8 --- /dev/null +++ b/zh-traditional/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -0,0 +1,11 @@ +# 如何使用嵌入型语言 +[//]: # (Version:1.0.0) +把一种编程语言嵌入到一个系统对程序员来讲有着几乎与性一样的魔力。这是一种最具有创造力的可以表现的行为。这使得系统惊人地强大。这也允许你锻炼大多数创造性和有生命力的能力,把系统变成你的朋友。 + +世界上最好的文本编辑器都有嵌入性语言。这可以被用于预计的观众可以掌握的语言的范围,语言的使用可以变为可选的,正如文本编辑器里那样,这样在一开始可以使用它,而没有其他人必须使用它。 + +我和许多其他的程序员曾坠入创造特殊目的的嵌入型语言的困境里。我曾经历过两次。已经存在了许多为嵌入型语言设计的语言,在创造一个新的语言前,你应该三思。 + +使用嵌入型语言前,真实的需要自问的问题是:这种工作与我的观众的文化是一致还是相悖?如果你的目标观众都是非程序员,这会有帮助吗?如果你的目标观众都是非程序员,他们会更喜欢 API 吗?他会是什么语言?程序员不会想要学习一种新的使用范围很窄的语言,但如果这与他们的文化混在一起了,他们将不会花太多时间去学习它。创造一种新的语言是一种快乐。但我们不应该让这遮蔽了观察用户的双眼。除非你有一些真正原始的需求与想法,为什么不使用一种已存在的语言呢?这样你就可以利用好用户对它已有的这种熟悉了。 + +Next [选择语言](03-Choosing-Languages.md) diff --git a/zh-traditional/3-Advanced/Technical-Judgment/03-Choosing-Languages.md b/zh-traditional/3-Advanced/Technical-Judgment/03-Choosing-Languages.md new file mode 100644 index 0000000..09cc157 --- /dev/null +++ b/zh-traditional/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -0,0 +1,15 @@ +# 选择语言 +[//]: # (Version:1.0.0) +喜欢程序员这份工作的独立的程序员可以为任务选择最好的语言。大多数职业程序员控制不了他们将要使用的语言。通常,这个话题会由执行行政决议而非技术决议的 boss 说出,他们缺少勇气去提升新型工具,即使他们知道,大多数时候使用最新的知识,最少被接受的工具是最好的。另一些情况下,这种团体中真实的好处,以及拓展一个更大的社区的好处,排除了个人的选择。通常管理者由能够雇用在给定的语言有些经验的程序员的需求所驱动。毫无疑问他们服务于他们所追求的,以成为工程或公司的最佳乐趣,而且他们会以此被尊敬。并且,我个人相信,这种最浪费而且错误的常见行为,你很有可能遇到。 + +但是,当然,事物永远不会是一维的。即使一种核心语言妥协了,超出了你的控制范围,通常的情况是,工具和其他程序可以且应该由另一种不同的语言来编写。如果一种语言需要作为嵌入型的(你通常都要考虑它!),语言的选择很大程度上会依赖于使用者的文化。一个人应该利用好这个问题来为你的公司或工程服务,为任务使用最好的语言,这样可以让工作变得有趣。 + +一门编程语言,如果学习它比学习自然语言还要难,那它真的应该被称为符号。对初学者和一些门外汉来说“学习一门新语言”像是一个令人生畏的任务,但在你掌握了三种语言后,这只是一个熟悉可用的库的简单问题。一个程序员趋向于思考一个由三四门语言组成的一个大杂烩系统,但我认为这样一个系统在以下几方面要比单一语言系统在很多情况下要强大: + +- 不同符号编写的部分间,必要的松耦合存在(虽然可能没有干净的接口) +- 通过独立重写每个组件,你可以轻松地写出一个新的语言平台 +- 只有一门语言可能对一个庞大的系统不太适合 - 你的多个模块由多种语言组成,能让你为任务找到正确的工具。 + +这些效应可能有些只是心理上的,但心理上的东西也很重要。最后要说的是,语言暴政的代价超过了它能提供的所有好处。 + +Next [明智地妥协 - 如何与时间压力斗争](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/zh-traditional/4-Glossary.md b/zh-traditional/4-Glossary.md new file mode 100644 index 0000000..de32ba9 --- /dev/null +++ b/zh-traditional/4-Glossary.md @@ -0,0 +1,110 @@ +# 词汇表 +[//]: # (Version:1.0.0) +这是这篇文章里用到的一些短语的词汇表。它们不一定是人们熟悉的标准含义,Eric S. Raymond 曾经编译过一份信息量巨大的词汇表 [HackerDict],如果你能理解其中的一些片段,阅读这个词汇表将是惊喜而愉悦的。 + +**unk-unk** +: unknown-unknown 的简写。指的是一些暂时不能被概念化的问题,它们会偷走项目的时间并且阻塞时间表。 + +**boss** +: 给你任务的人或实体,有些地方可能泛指公众。 + +**printlining** +: 在严格的临时机制上,在程序中插入一些语句,为调试输出一些程序执行过程中的信息。 + +**logging** +: 实践中编写程序的一种方式,使得它能够产生可设置的输出以描述它的执行过程。 + +**分治** +: 一种自上而下设计的技术,更重要的是,一种调试的技术,划分问题或谜题为小的问题或谜题。 + +**vapour** +: 幻觉,而且通常是对还不能出售的软件虚假的承诺,往往不会物质化为任何固定的东西。 + +**boss** +: 给你设定任务的人,有些时候,也指用户。 + +**tribe** +: 与你一同为相同目标奋斗的人们。 + +**低垂的水果** +: 轻易能达到的巨大提升。 + +**主办人** +:项目的发起人 + +**垃圾** +: 不再需要被放在内存中的对象 + +**商业** +: 一群为财富聚合在一起的人 + +**公司** +: 一群为财富聚合在一起的人 + +**集体** +: 一群与你共享文化亲缘与忠诚的人。 + +**滚动目盲** +: 一种由于有效信息被太多无效信息掩盖导致你不能发现它的效应 + +**挂钟** +: 由挂钟测量的现实中真实的时间,与 CPU 时间相对。 + +**瓶颈** +: 系统性能最重要的限制/一个可以限制性能的界限。 + +**主线** +: 一个独特的信息块,所有缓存副本都从它继承而来,作为这份数据的官方版本。 + +**分配的堆** +: 一份内存在这样的情况下可以被称为分配了堆:当释放它的机制已经完成时。 + +**垃圾** +: 已经被分配但不再有有效意义的内存。 + +**GC** +: 一个回收垃圾的系统。 + +**内存泄露** +: 无意持有的一系列对象的引用,它们避免了垃圾回收(或者垃圾回收器或内存管理系统中的 bug!)导致程序随时间逐渐增加了它的内存占用。 + +**极限编程** +: 一种强调与客户交流以及自动化测试的编程风格。 + +**碰壁** +: 因为耗尽了某种特定的资源导致性能突然大幅度地降级 + +**投机编程** +: 在知道一个东西有用前就把它做出来。 + +**信息隐藏(封装)** +: 通过使用尽可能少暴露信息的接口来让事情保持独立解耦的一种设计原则。 + +**面向对象编程** +: 一种强调在对象内部管理状态的编程风格。 + +**交流语言** +: 一种优先为标准化而非执行设计的语言。 + +**箱子与箭头** +: 一种宽松,非正式的,由箱子和箭头组合而成表达关系的图表制作风格,这与正式的图表方法论,比如 UML,相对。 + +**通用语** +: 一种语言是如此受欢迎以至于它成了它的领域中实际上的标准,例如法语一度成为国际外交的手段。 + +**buy vs. build** +: 用来形容购买软件还是自己编写软件这样的选择。 + +**合并工作** +: 需要很少创造力并产生很少风险的工作,合并工作可以被很容易地评估。 + +**编程符号** +: 编程语言的同义词,强调编程语言的数学本质以及它们与自然语言相比的简单之处。 + +**稻草人** +: 一种用来作为技术讨论起点的文档。稻草人也可以引申出火柴人,罐头人,木头人,铁人,等等。 + +**白纸** +: 一种信息文档,通常用来解释或将产品或思想卖给观众而非程序员。 + +Next [书籍/网站](5-Bibliography.md) diff --git a/zh-traditional/5-Bibliography.md b/zh-traditional/5-Bibliography.md new file mode 100644 index 0000000..a3e97a6 --- /dev/null +++ b/zh-traditional/5-Bibliography.md @@ -0,0 +1,31 @@ +# 附录 A - 书目/网站目录 +[//]: # (Version:1.0.0) +## 书目 + +[Rules00] Guy Kawasaki, Michelle Moreno, and Gary Kawasaki. 2000. HarperBusiness. Rules for Revolutionaries: The Capitalist Manifesto for Creating and Marketing New Products and Services. + +[RDev96] Steve McConnell. 1996. Microsoft Press. Redmond, Wash. Rapid Development: Taming Wild Software Schedules. + +[CodeC93] Steve McConnell. 1993. Microsoft Press. Redmond, Wash. Code Complete. + +[XP99] Kent Beck. 1999. 0201616416. Addison-Wesley. Extreme Programming Explained: Embrace Change. + +[PlanXP00] Kent Beck and Martin Fowler. 2000. 0201710919. Addison-Wesley. Planning Extreme Programming. + +[Prag99] Andrew Hunt, David Thomas, and Ward Cunningham. 1999. 020161622X. Addison-Wesley. The Pragmatic Programmer: From Journeyman to Master. + +[Stronger] Friedrich Nietzsche. 1889. Twilight of the Idols, "Maxims and Arrows", section 8.. + +## 网站 + +[PGSite] Paul Graham. 2002. Articles on his website: [http://www.paulgraham.com/articles.html](http://www.paulgraham.com/articles.html). All of them, but especially "Beating the Averages". + +[Hacker] Eric S. Raymond. 2003. How to Become a Hacker. [http://www.catb.org/~esr/faqs/hacker-howto.html](http://www.catb.org/~esr/faqs/hacker-howto.html). + +[HackDict] Eric S. Raymond. 2003. The New Hacker Dictionary. [http://catb.org/esr/jargon/jargon.html](http://catb.org/esr/jargon/jargon.html). + +[ExpCS] Edsger W. Dijkstra. 1986. How Experimental is Computing Science?. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF). + +[Knife] Edsger W. Dijkstra. 1984. On a Cultural Gap. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF). + +Next [History](6-History.md) diff --git a/zh-traditional/6-History.md b/zh-traditional/6-History.md new file mode 100644 index 0000000..e6edd54 --- /dev/null +++ b/zh-traditional/6-History.md @@ -0,0 +1,47 @@ +# 附录 B - 历史 +[//]: # (Version:1.0.0) +## 迁移到 Github + +这篇文章已经在 github 上作为一个仓库创建了,这样它可以很容易地被分享、更新、提高。它是从这里复制过来的。[http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm) by [Braydie Grove](https://github.com/braydie)。 2016年1月迁移到 github。 + +## 希望反馈或扩展。 + +请将你对这篇文章的任何评论发给我,我会考虑所有的建议,大部分都会对这篇文章有所帮助。 + +这篇文章处于 GNU 免费文档授权下。这个授权不是专门为文章而设计的。文章通常有连贯的令人信服的服务于一个中心的论据。我希望这篇文章尽量短而易读。 + +我希望它是说明性的,尽管不是一本教科书,它被划分成许多小节,这样新的章节可以被自由地添加进去。有了这样的倾向,你可以用你觉得合适的方式来扩展这篇文章,且服从这个授权的规定。 + +可能认为这个文档值得扩展有点自大,但希望生生不息。我会很高兴看到你用以下的方式扩展它: + +对每个章节增加一些阅读理解, + +增加更多章节, + +翻译为其他语言,即使只是一小部分一小部分地翻译,或者 + +在文字间留下批评或评论, + +用不同形式构建的能力:比如 palm 格式或更好的 HTML 格式。 + +如果你向我传达了你的工作,我会考虑把它包括在我的子版本里,遵循这个许可证的规定。你也可以在我的了解之外制作你自己的版本,正如这个协议所说的。 + +Thank you. + +Robert L. Read + +## 原始版本 + +这个文档的原始版本由 Robert L. Read 在2000年制作,并且以电子形式在2002年首发于 Samizdat Press(http://Samizdat.mines.edu) 。被 Hire.com 的程序员所使用。 + +在这篇文章2003年被 Slashdot 刊载后,大概有75个人给我发过邮件提过建议与错误修改。我感激他们中的所有人。可能有很多重复,但这些人不是提出来最主要的建议就是第一个找到了我的 bug:Morgan McGuire, David Mason, Tom Moertel, Ninja Programmer (145252) at Slashdot, Ben Vierck, Rob Hafernik, Mark Howe, Pieter Pareit, Brian Grayson, Zed A. Shaw, Steve Benz, Maksim Ioffe, Andrew Wu, David Jeschke, 以及 Tom Corcoran。 + +最后,我想感谢 Christina Vallery,他的编辑和校对巨大地提高了第二份草稿,还有 Wayne Allen,他鼓励我开始了这件事情。 + +## 原始作者的简介 + +Robert L. Read 生活在德克萨斯,奥斯汀, 有一个妻子和两个孩子,他现在是 Hire.com 的首席工程师。他在那里工作了四年。在这之前他建立了 4R 科技,为造纸工业生产基于扫描的图像分析质量控制工具。 + +Rob 在1995年在德州大学获得数据库理论方向的计算机博士学位。1987年他在 Rice 大学获得计算机科学学士学位,在16岁时,他就是一个带薪程序员了。 + +Next [License](LICENSE.md) diff --git a/zh-traditional/7-Contributions.md b/zh-traditional/7-Contributions.md new file mode 100644 index 0000000..3ea8b14 --- /dev/null +++ b/zh-traditional/7-Contributions.md @@ -0,0 +1,33 @@ +# Contributions +[//]: # (Version:1.0.0) +这个仓库目标是成为一个社区驱动的工程,你的加入会极大地促进这个向导的质量。 + +## 我可以做什么贡献? + +有很多方式为 "How to be a Programmer" 做贡献 + +- 新章节的思想 +- 提升已有的章节 +- 识别排版错误或其他章节中的问题 +- 为章节提供额外的资源链接 +- 一般的用于提升工程的建议 +- 为这份指导提供翻译 + +## 翻译 + +当前,这份指导已经从英文翻译为以下语言: + +- 中文 by [ahangchen](https://github.com/ahangchen) + + **如果你第一个提供了其他语言的翻译,你就是这个工程的一个明确的贡献者,请帮忙维护和 review 对翻译版本的修改。** + + +## 贡献者 + +Github 在这里会维护一个所有贡献者的列表 [contributors](https://github.com/braydie/HowToBeAProgrammer/graphs/contributors) + +## 校正与迁移到GitHub + +[Braydie Grove](https://www.github.com/braydie) 已经同意作为主编。 + +Braydie 把原始的文档转成了 Markdown 的形式并创建了这个仓库。 diff --git a/zh-traditional/LICENSE.md b/zh-traditional/LICENSE.md new file mode 100644 index 0000000..e579b65 --- /dev/null +++ b/zh-traditional/LICENSE.md @@ -0,0 +1,12 @@ + +## Creative Commons Attribution Share-Alike +[//]: # (Version:1.0.0) +"How To Be A Programmer: Community Version" by Robert L. Read with Community is licensed under Creative Commons Attribution Share-Alike Internal v 4.0. + +At present this work will be edited by Braydie Grove and Robert L. Read. + +We will make reasonable attempts to maintain proper attributions of contributions in the section entittle "Contributions". If you make a pull-request with a significant contribution, please add a very brief description of your contribution to that section. + + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/zh-traditional/README.md b/zh-traditional/README.md new file mode 100644 index 0000000..70e34cb --- /dev/null +++ b/zh-traditional/README.md @@ -0,0 +1,112 @@ +# How to be a Programmer 中文版 +Robert L. Read with Community +[//]: # (Version:1.0.0) +Copyright 2002, 2003, 2016 Robert L. Read + +Licensed under [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +翻译:[梦里风林](https://github.com/ahangchen) + +原文:[HowToBeAProgrammer](https://github.com/braydie/HowToBeAProgrammer) + +如果您希望改进这份中文翻译,请向这个[分支](https://github.com/ahangchen/HowToBeAProgrammer)提交Pull request。 + +[可以在gitbook在线阅读或导出PDF。](https://braydie.gitbooks.io/how-to-be-a-programmer/content/zh/index.html) + +文章中出现的一些词汇往往有特殊的含义,可以在[4-词汇表](4-Glossary.md)找到注释。 + +## 引言 +  做一个好的程序员,困难而高尚。将一个软件工程集体愿景变为现实,最困难的地方在于与你的同事和顾客相处。编程很重要,这需要强大的智力和技能。 但在好的程序员看来,相比构建一个让客户和各种各样的同事都满意的软件系统,(纯粹的)编程真的只是小孩子的玩意。在这篇文章里,我尝试尽可能简洁地总结那些当我21岁时,希望别人告诉我的事。 + +  这可能很主观的,所以,这篇文章注定不适用于所有人,并且有的内容有点武断。我尽量写一些程序员在ta的工作中,非常可能会遇到的事情。大部分这些问题以及它们的解决方案在人们的环境中如此普遍,以至于我(说的)可能有点唠叨。尽管如此,我还是希望这篇文章是有用的。 + +  我们在课堂上学习编程。 那些著作: The Pragmatic Programmer [Prag99], Code Complete [CodeC93], Rapid Development [RDev96], 以及 Extreme Programming Explained [XP99] 都传授编程(知识),并阐述做一个好的程序员这个大话题。 在读这篇文章之前,或者就是现在,你当然也应该读一读Paul Graham [PGSite] 和 Eric Raymond [Hacker] 的文章。 但与那些著作不同,这篇文章强调社交问题并且总结了整套我所知的必须的技能。 + +  在这篇文章里,boss这个词指的是任何一个交给你工程去做的人。 除了一些语境外,我会同义地使用交易,公司,集体这些词,比如,交易意味着赚钱,公司意味着现代的工作空间,集体一般是那些你一起工作的人。 + +  欢迎来到这个群体。 + +## 目录 + +1. [入门](1-Beginner) + - 个人技能 + - [学会 Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [如何通过分割问题 Debug](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一个错误](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日志调试](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能问题](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解决性能问题](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何优化循环](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何处理 I/O 开销](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理内存](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [如何处理偶现的 Bug](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何学习设计技能](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何进行实验](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - 团队技能 + - [为什么预估很重要](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [如何预估编程时间](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人们作为信息源](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何优雅地写文档](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代码上工作](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代码控制](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何进行单元测试](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [毫无头绪?休息一下](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何决定下班时间](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何与不好相处的人相处](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [进阶](2-Intermediate) + - 个人技能 + - [如何保持活力](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被广泛信任](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在时间和空间之间该如何权衡](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何进行压力测试](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [如何权衡简洁与抽象](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何学习新技能](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [学会打字](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [如何进行集成测试](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流语言](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [重型工具](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [如何分析数据](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - 团队技能 + - [如何管理开发时间](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方软件风险](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理咨询](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [如何适度交流](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言异议以及如何避免](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - 评判 + - [如何权衡开发质量与开发时间](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理软件系统依赖](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何评判软件是否太不成熟了](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何决定购买还是构建](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何专业地成长](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [如何评估面试者](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何决定什么时候使用奇妙的计算机科学](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何与非工程师交谈](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [高级](3-Advanced) + - 技术评判 + - [如何从不可能中找到困难的部分](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型语言](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [选择语言](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - 机智地妥协 + - [如何与时间压力作斗争](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用户](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何获得晋升](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - 服务你的团队 + - [如何发展才能](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何选择工作内容](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何让你队友的价值最大化](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何划分问题](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何处理无聊的问题](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何为工程获取支持](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何发展一个系统](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地沟通](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告诉人们他们不想听的东西](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何处理管理神话](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何处理混乱的组织](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [词汇表](4-Glossary.md) +5. [附录 A - 书籍/网站](5-Bibliography.md) +6. [附录 B - 历史 (至2016年1月)](6-History.md) +6. [附录 C - 贡献 (至2016年1月)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/zh-traditional/SUMMARY.md b/zh-traditional/SUMMARY.md new file mode 100644 index 0000000..34ec39e --- /dev/null +++ b/zh-traditional/SUMMARY.md @@ -0,0 +1,86 @@ +# How to be a Programmer 正體中文版 +[//]: # (Version:1.0.0) +原文出自 https://github.com/braydie/HowToBeAProgrammer +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. + +## 目錄 + +1. [入門](1-Beginner/README.md) + - 技能 + - [學習除錯](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [如何通過分割問題 Debug](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一個錯誤](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日誌調試](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能問題](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解決性能問題](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何優化循環](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何處理 I/O 開銷](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理內存](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [如何處理偶現的 Bug](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何學習設計技能](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何進行實驗](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - 團隊技能 + - [為什麼預估很重要](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [如何預估編程時間](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人們作為信息源](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何優雅地寫文檔](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代碼上工作](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代碼控制](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何進行單元測試](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [毫無頭緒?休息一下](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何決定下班時間](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何與不好相處的人相處](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [進階](2-Intermediate/README.md) + - 個人技能 + - [如何保持活力](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被廣泛信任](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在時間和空間之間該如何權衡](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何進行壓力測試](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [如何權衡簡潔與抽象](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何學習新技能](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [學會打字](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [如何進行集成測試](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流語言](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [重型工具](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [如何分析數據](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - 團隊技能 + - [如何管理開發時間](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方軟件風險](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理諮詢](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [如何適度交流](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言異議以及如何避免](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - 評判 + - [如何權衡開發品質與開發時間](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理軟件系統依賴](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何評判一個軟件是否太不成熟了](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何決定購買還是構建](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何專業地成長](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [如何評估面試者](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何決定什麼時候使用奇妙的計算機科學](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何與非工程師交談](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [高級](3-Advanced/README.md) + - 技術評判 + - [如何從不可能中找到困難的部分](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型語言](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [選擇語言](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - 機智地妥協 + - [如何與時間壓力作鬥爭](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用戶](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何獲得晉升](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - 服務你的團隊 + - [如何發展才能](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何選擇工作內容](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何讓你隊友的價值最大化](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何劃分問題](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何處理無趣的問題](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何為工程獲取支持](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何發展一個系統](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地溝通](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告訴人們他們不想聽的東西](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何處理管理神話](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何處理混亂的組織](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [詞彙表](4-Glossary.md) +5. [附錄 A - 書籍/網站](5-Bibliography.md) +6. [附錄 B - 歷史 (至2016年1月)](6-History.md) +6. [附錄 C - 貢獻 (至2016年1月)](7-Contributions.md) diff --git a/zh/1-Beginner/Personal-Skills/01-Learn-To-Debug.md b/zh/1-Beginner/Personal-Skills/01-Learn-To-Debug.md new file mode 100644 index 0000000..a118b46 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/01-Learn-To-Debug.md @@ -0,0 +1,22 @@ +# 学会 Debug +[//]: # (Version:1.0.0) +调试(Debug)是成为一个程序员的基石。调试这个词第一个含义即是移除错误,但真正有意义的含义是,通过检查来观察程序的运行。一个不会调试的程序员等同于瞎子。 + +理想主义者认为设计、分析、复杂的理论或其他东西,是更基本的东西,他们不是现实的程序员。现实的程序员不会活在理想的世界里。即使你是完美的,你也需要与在你周围的主要软件公司或组织 (比如-GNU-) 的代码,和你同事写的代码打交道。这里面大部分的代码以及它们的文档是不完美的。如果不能看透代码的具体执行过程,最轻微的颠簸都会把你永远地抛出去。通常这种可见性只能从实验获得,也就是,调试。 + +调试是一件与程序运行相关的事情,而非与程序本身相关。你从主要的软件公司购买一些产品,你通常不会看到(产品背后的)程序本身。但代码不遵循文档的情况(让你整台机器崩掉是一个常见又特殊的例子)或者文档没有说明的情况仍然会出现。更常见的是,你的程序出现了一个错误,当你检查你写的代码的时候,却不知道这个错误是怎么发生的。不可避免的,这意味着你做的一些假设并不对,或者一些你没有预料到的情况发生了。有时候,神奇的修改源代码的技巧可能会生效。当它无效时,你必须调试了。 + +为了获得一个程序执行过程的可见性,你必须能够执行代码并且从这个过程中观察到什么。有时候这是显而易见的,比如一些正在呈现在屏幕上的东西,或者两个事件之间的延迟。在许多其他的案例中,调试与一些不一定可见的东西相关,比如代码中一些变量的状态,哪一行代码正在被执行,或者一些断言是否持有了一个复杂的数据结构。这些隐藏的细节必须被显露出来。 + + +观察一个正在执行程序的内部的方法通常可按如下分类: + +- 使用一个调试工具; +- Printlining[(戳这里看释义)](../../4-Glossary.md) - 对程序做一个临时的修改,通常是加一些行去打印一些信息; +- 日志 - 用日志的形式为在程序的运行中创建一个永久的视窗。 + +当调试工具稳定可用时,它们是非常美妙的,但 [Printlining](../../4-Glossary.md) 和写日志甚至是更加重要的。调试工具通常落后于编程语言的发展,所以在某些时候它们都可能是无效的。另外,调试工具可能轻微改变程序实际执行的方式。最后,调试有许多种,比如检查一个断言和一个巨大的数据结构,这需要写代码并改变程序的运行。当调试工具可用时,知道如何使用调试工具是一件好事,但学会使用其他两种方式也是至关重要的。 + +当调试需要修改代码的时候,一些初学者会感到害怕。这是可以理解的,这有点像探索型外科手术。但你需要学会打破代码,让它跳起来,你需要学会在它上面做实验,并且需要知道你临时对它做的任何事情都不会使它变得更糟。如果你感受到了这份恐惧,找一位导师 - 就是因为许多人在一开始面对这种恐惧的的时候表现的太脆弱,我们因此失去了很多本可以变成优秀程序员的人。 + +Next [如何通过分离问题空间来 Debug](02-How-to-Debug-by-Splitting-the-Problem-Space.md) diff --git a/zh/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md b/zh/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md new file mode 100644 index 0000000..fd1da41 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md @@ -0,0 +1,15 @@ +# 如何通过分割问题 Debug +[//]: # (Version:1.0.0) +调试是有趣的,因为它一开始是个迷。你认为它应该这样做,但实际上它却那样做。很多时候并不仅是这么简单---我给出的任何例子都会被设计来与一些偶尔在现实中会发生的情况相比较。调试需要创造力与智谋。如果说调试有简单之道,那就是在这个谜题上使用分治法。 + +假如,你创建了一个程序,它会依次执行十件事情。当你运行它的时候,它却崩溃了。但你本来的目的并不是想让它崩溃,所以现在一个谜题扔给你了。当你查看输出时,你可以看到序列里前七件事情运行成功了。最后三件事情在输出里却看不到,所以你的谜题变小了:“它是在执行第8、9、10件事的时候崩溃的”。 + +你是否可以设计一个实验来观察它是在哪件事情上崩溃呢?当然,你可以用一个调试器或者我们可以在第8第9件事后面加一些[printlining](../../4-Glossary.md)的语句(或者你正在使用的任何语言里的等价的事情),当我们重新运行它的时候,我们的谜题会变得更小,比如“它是在做第九件事的时候崩溃的”。我发现,把谜题是怎样的一直清楚地记在心里能让我们保持注意力。当几个人在一个问题的压力下一起工作时,很容易忘记最重要的谜题是什么。 + +调试技术中分治的关键和算法设计里的分治是一样的。你只要从中间开始划分,就不用划分太多次,并且能快速地调试。但问题的中点在哪里?这就是真正需要创造力和经验的地方了。 + +对于一个真正的初学者来说,可能发生错误的地方好像在代码的每一行里都有。一开始,你看不到一些你稍后开发的时候才会看到的其它纬度,比如执行过的代码段,数据结构,内存管理,与外部代码的交互,一些有风险的代码,一些简单的代码。对于一个有经验的程序员,这些其他的维度为整个可能出错的事情展示了一个不完美但是有用的思维模型。拥有这样的思维模型能让一个人更高效地找到谜题的中点。 + +一旦你最终划分出了所有可能出错的地方,你必须试着判断错误躲在哪个地方。比如:这样一个谜题,哪一行未知的代码让我的程序崩溃了?你可以这样问自己,出错的代码是在我刚才执行的程序中间的那行代码的前面还是后面?通常你不会那么幸运就能知道错误在哪行代码甚至是哪个代码块。通常谜题更像这个样子的:“图中的一个指针指向了错误的结点还是我的算法里变量自增的代码没有生效?”,在这种情况下你需要写一个小程序去确认图中的指针是否都是对的,来决定分治后的哪个部分可以被排除。 + +Next [如何移除错误](03-How-to-Remove-an-Error.md) diff --git a/zh/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md b/zh/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md new file mode 100644 index 0000000..34a55c8 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md @@ -0,0 +1,9 @@ +# 如何移除一个错误 +[//]: # (Version:1.0.0) +我曾有意把检查程序执行和修复错误分割开来,但是当然,调试也意味着移除 bug。理想状况下,当你完美的发现了错误以及它的修复方法时,你会对代码有完美的理解,并且有一种顿悟(啊哈!)的感觉。但由于你的程序会经常使用其他不具有可视性的、没有一致性注释的系统(比如第三方库),所以完美是不可能的。在其他情况下,可能代码是如此的复杂以至于你的理解可能并不完美。 + +在修复 bug 时,你可能想要做最小的改变来修复它。你可能看到一些其他需要改进的东西,但不会同时去改进他们。请使用科学的方法去改进一个东西,并且一次只改变一个东西。修复 bug 最好的方式是能够重现 bug,然后把你的修复替换进去,重新运行你的程序,观察,直到 bug 不再出现。当然,有时候不止一行代码需要修改,但你在逻辑上仍然需要使用一个独立原子(译者注:以前人们认为原子不可再分,所以用用原子来代表不可再分的东西)的改变来修复这个 bug。 + +有时候,可能实际上有几个 bug,但表现出来好像是一个。这取决于你怎么定义 bug,你需要一个一个地修复它们。有时候,程序应该做什么或者原始作者想要做什么是不清晰的。在这种情况下,你必须多加练习,增加经验,评判并为代码赋予你自己的认知。决定它应该做什么,并注释或用其他方式阐述清楚,然后修改代码以遵循你赋予的含义。这是一个进阶或高级的技能,有时甚至比一开始用原始的方式创建这些代码还难,但真实的世界经常是混乱的。你必须修复一个你不能重写的系统。 + +Next [如何使用日志调试](04-How-to-Debug-Using-a-Log.md) diff --git a/zh/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md b/zh/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md new file mode 100644 index 0000000..ac1dddc --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md @@ -0,0 +1,13 @@ +# 如何使用日志调试 +[//]: # (Version:1.0.0) +*Logging*(日志)是一种编写系统的方式,可以产生一系列信息记录,被称为 log。*Printlining* 只是输出简单的,通常是临时的日志。初学者一定要理解并且使用日志,因为他们对编程的理解是局限的。因为系统的复杂性,系统架构必须理解与使用日志。在理想的状态下,程序运行时产生的日志信息数量需要是可配置的。通常,日志提供了下面三个基本的优点: + +- 日志可以提供一些难以重现的 bug 的有效信息,比如在产品环境中发生的、不能在测试环境重现的 bug。 +- 日志可以提供统计和与性能相关的数据,比如语句间流逝过的时间。 +- 可配置的情况下,日志允许我们获取普通的信息,使得我们可以在不修改或重新部署代码的情况下调试以处理具体的问题。 + +需要输出的日志数量总是一个简约与信息量的权衡。太多的信息会使得日志变得昂贵,并且造成[*滚动目盲*](../../4-Glossary.md),使得发现你想要的信息变得很困难。但信息太少的话,日志可能不包含你需要的信息。出于这个原因,让日志的输出可配置是非常有用的。通常,日志中的每个记录会标记它在源代码里的位置,执行它的线程(如果可用的话),时间精度,并且通常还有一些额外的有效信息,比如一些变量的值,剩余内存大小,数据对象的数量,等等。这些日志语句撒遍源码,但只出现在主要的功能点和一些可能出现危机的代码里。每个语句可以被赋予一个等级,并且只有在系统被配置成输出相应等级的记录的时候才输出这个等级的记录。你应该设计好日志语句来标记你预期的问题。预估测量程序表现的必要性。 + +如果你有一个永久的日志,printling 现在可以用日志的形式来完成,并且一些调试语句可能会永久地加入日志系统。 + +Next [如何理解性能问题](05-How-to-Understand-Performance-Problems.md) diff --git a/zh/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md b/zh/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md new file mode 100644 index 0000000..8c0bf70 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md @@ -0,0 +1,11 @@ +# 如何理解性能问题 +[//]: # (Version:1.0.0) +学习理解运行的程序的性能问题与学习 debug 是一样不可避免的。即使你完美、精确地理解了你的代码运行时所产生的开销,你的代码也会调用其他你几乎不能控制的或者几乎不可看透的软件系统。然而,实际上,通常性能问题和调试有点不一样,而且往往要更简单些。 + +假如你或你的客户认为你的一个系统或子系统运行太慢了。在你把它变快之前,你必须构建一个它为什么慢的思维模型。为了做到这个,你可以使用一个图表工具或者一个好的日志,去发现时间或资源真正被花费在什么地方。有一句很有名的格言:90%的时间会花费在10%的代码上。在性能这个话题上,我想补充的是输入输出开销的重要性。通常大部分时间是以某种形式花费在 I/O 上。发现昂贵的 I/O 和昂贵的10%代码是构建思维模型的一个好的开始。 + +计算机系统的性能有很多个维度,很多资源会被消耗。第一种资源是“挂钟时间”,即执行程序的所有时间。记录“挂钟时间”是一件特别有价值的事情,因为它可以告诉我们一些图表工具表现不了的不可预知的情况。然而,这并不总是描绘了整幅图景。有时候有些东西只是稍微多花费了一点点时间,并且不会引爆什么问题,所以在你真实要处理的计算机环境中,多一些处理器时间可能会是更好的选择。相似的,内存,网络带宽,数据库或其他服务器访问,可能最后都比处理器时间要更加昂贵。 + +竞争共享的资源被同步使用,可能导致死锁和互斥。死锁是由于不恰当的同步和请求资源导致线程执行能力的丧失。互斥是对于资源访问的不恰当安排。如果这是可以预料到的,最好在你的项目开始前就采取措施来地衡量线程争抢。即使线程争抢不会发生,对于有效维护它们也是很有帮助的。 + +Next [如何修复性能问题](06-How-to-Fix-Performance-Problems.md) diff --git a/zh/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md b/zh/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md new file mode 100644 index 0000000..69e3f37 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md @@ -0,0 +1,13 @@ +# 如何修复性能问题 +[//]: # (Version:1.0.0) +大部分软件都可以通过付出相对较小的努力,让他们比刚发布时快上10到100倍。在市场的压力下,选择一个简单而快速的解决问题的方法是比选择其它方法更为明智而有效率的选择。然而,性能是可用性的一部分,而且通常它也需要被更仔细地考虑。 + +提高一个非常复杂的系统的性能的关键是,充分分析它,来发现其“瓶颈”,或者其资源耗费的地方。优化一个只占用1%执行时间的函数是没有多大意义的。一个简要的原则是,你在做任何事情之前必须仔细思考,除非你认为它能够使系统或者它的一个重要部分至少快两倍。通常会有一种方法来达到这个效果。考虑你的修改会带来的测试以及质量保证的工作需要。每个修改带来一个测试负担,所以最好这个修改能带来一点大的优化。 + +当你在某个方面做了一个两倍提升后,你需要至少重新考虑并且可能重新分析,去发现系统中下一个最昂贵的瓶颈,并且攻破那个瓶颈,得到下一个两倍提升。 + +通常,性能的瓶颈的一个例子是,数牛的数目:通过数脚的数量然后除以4,还是数头的数量。举些例子,我曾犯过的一些错误:没能在关系数据库中,为我经常查询的那一列提供适当的索引,这可能会使得它至少慢了20倍。其他例子还包括在循环里做不必要的 I/O 操作,留下不再需要的调试语句,不再需要的内存分配,还有,尤其是,不专业地使用库和其他的没有为性能充分编写过的子系统。这种提升有时候被叫做“低垂的水果”,意思是它可以被轻易地获取,然后产生巨大的好处。 + +你在用完这些“低垂的水果”之后,应该做些什么呢?你可以爬高一点,或者把树锯倒。你可以继续做小的改进或者你可以严肃地重构整个系统或者一个子系统。(不只是在新的设计里,在信任你的 boss 这方面,作为一个好的程序员,这是一个非常好的使用你的技能的机会)然而,在你考虑重构子系统之前,你应该问你自己,你的建议是否会让它好五倍到十倍。 + +Next [如何优化循环](07-How-to-Optimize-Loops.md) diff --git a/zh/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md b/zh/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md new file mode 100644 index 0000000..4059d6d --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md @@ -0,0 +1,15 @@ +# 如何优化循环 +[//]: # (Version:1.0.0) +有时候你会遇到循环,或者递归函数,它们会花费很长的执行时间,可能是你的产品的瓶颈。在你尝试使循环变得快一点之前,花几分钟考虑是否有可能把它整个移除掉,有没有一个不同的算法?你可以在计算时做一些其他的事情吗?如果你不能找到一个方法去绕开它,你可以优化这个循环了。这是很简单的,move stuff out。最后,这不仅需要智慧而且需要理解每一种语句和表达式的开销。这里是一些建议: + +- 删除浮点运算操作。 +- 非必要时不要分配新的内存。 +- 把常量都放在一起声明。 +- 把 I/O 放在缓冲里做。 +- 尽量不使用除法。 +- 尽量不适用昂贵的类型转换。 +- 移动指针而非重新计算索引。 + +这些操作的具体代价取决于你的具体系统。在一些系统中,编译器和硬件会为你做一些事情。但必须清楚,有效的代码比需要在特殊平台下理解的代码要好。 + +Next [如何处理I/O开销](08-How-to-Deal-with-IO-Expense.md) diff --git a/zh/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md b/zh/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md new file mode 100644 index 0000000..1c3e712 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md @@ -0,0 +1,13 @@ +# 如何处理I/O代价 +[//]: # (Version:1.0.0) +在很多问题上,处理器的速度比硬件交流要快得多。这种代价通常是小的 I/O,可能包括网络消耗,磁盘 I/O,数据库查询,文件 I/O,还有其他与处理器不太接近的硬件使用。所以构建一个快速的系统通常是一个提高 I/O,而非在紧凑的循环里优化代码或者甚至优化算法的问题。 + +有两种基本的技术来优化 I/O:缓存和代表(译者注:比如用短的字符代表长的字符)。缓存是通过本地存储数据的副本,再次获取数据时就不需要再执行 I/O,以此来避免 I/O(通常避免读取一些抽象的值)。缓存的关键在于要让哪些数据是主干的,哪些数据是副本变得显而易见。主干的数据只有一份(在一个更新周期里)。缓存有这样一种危险:副本有时候不能立刻反映主干的修改。 + +代表是通过更高效地表示数据来让 I/O 更廉价。这通常会限制其他的要求,比如可读性和可移植性。 + +代表通常可以用他们第一实现中的两到三个因子来做优化。实现这点的技术包括使用二进制表示而非人类可识别的方式,传递数据的同时也传递一个符号表,这样长的符号就不需要被编码,一个极端的例子是哈弗曼编码。 + +另一种有时能够用来优化本地引用的技术是让计算更接近数据。例如,如果你正在从数据库读取一些数据并且在它上面执行一些简单的计算,比如求和,试着让数据库服务器去做这件事,这高度依赖于你正在工作的系统的类型,但这个方面你必须自己探索。 + +Next [如何管理内存](09-How-to-Manage-Memory.md) diff --git a/zh/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md b/zh/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md new file mode 100644 index 0000000..969f265 --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md @@ -0,0 +1,15 @@ +# 如何管理内存 +[//]: # (Version:1.0.0) +内存是一种你不可以耗尽的珍贵资源。在一段时期里,你可以无视它,但最终你必须决定如何管理内存。 + +堆内存是在单一子程序范围外,需要持续(保留)的空间。一大块内存,在没有东西指向它的时候,是无用的,因此被称为*垃圾*。根据你所使用的系统的不同,你可能需要自己显式释放将要变成垃圾的内存。更多时候你可能使用一个有*垃圾回收器*的系统。一个垃圾回收器会自己注意到垃圾的存在并且在不需要程序员做任何事情的情况下释放它的内存空间。垃圾回收器是奇妙的:它减小了错误,然后增加了代码的简洁性。如果可以的话,使用垃圾回收器。 + +但是即使有了垃圾回收机制,你还是可能把所有的内存填满垃圾。一个典型的错误是把哈希表作为一个缓存,但是忘了删除对哈希表的引用。因为引用仍然存在,被引用者是不可回收但却无用的。这就叫做*内存泄露*。你应该尽早发现并且修复内存泄露。如果你有一个长时间运行的系统,内存可能在测试中不会被耗尽,但可能在用户那里被耗尽。 + +创建新对象在任何系统里都是有点昂贵的。然而,在子程序里直接为局部变量分配内存通常很便宜,因为释放它的策略很简单。你应该避免不必要的对象创建。 + +当你可以定义你一次需要的数量的上界的时候,一个重要的情况出现了:如果这些对象都占用相同大小的内存,你可以使用单独的一块内存,或缓存,来持有所有的这些对象。你需要的对象可以在这个缓存里以循环的方式分配和释放,所以它有时候被称为环缓存。这通常比堆内存分配更快。(译者注:这也被称为对象池。) + +有时候你需要显式释放已分配的内存,所以它可以被重新分配而非依赖于垃圾回收机制。然后你必须谨慎机智地分配每一块内存,并且为它设计一种在合适的时候重新分配的方式。这种销毁的方式可能随着你创建的对象的不同而不同。你必须保证每个内存分配操作都与一个内存释放操作相匹配。(译者注:在C里面,no malloc no free,在C++里面,no new no delete)。这通常是很困难的,所以程序员通常会实现一种简单的方式或者垃圾回收机制,比如引用计数,来为它们做这件事情。 + +Next [如何处理偶现的 Bug](10-How-to-Deal-with-Intermittent-Bugs.md) diff --git a/zh/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md b/zh/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md new file mode 100644 index 0000000..3fb5f8a --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md @@ -0,0 +1,17 @@ +# 如何处理偶现的 Bugs +[//]: # (Version:1.0.0) +偶现 bug 是一种类似于外太空50足隐身蝎子的东西。这种噩梦是如此稀少以至于它很难观察,但其出现频率使得它不能被忽视。你不能调试因为你不能找到它。 + +尽管在8个小时后你会开始怀疑,偶现的 bug 必须像其他事情一样遵循相同的逻辑规律。但困难的是它只发生在一些未知的情形。尝试着去记录这个 bug 出现时的情景,这样你可以去推测到底是什么样的可变性。情况可能跟数据的值相关,比如“这只是在我们把*Wyoming*作为一个值输入时发生”,如果这不是可变性的根源,下一个怀疑应该是不合适的同步并发。 + +尝试,尝试,尝试去在一种可控的方式下重现这个 bug。如果你不能重现它,用日志系统给它设置一个圈套,来在你需要的时候,在它真的发生的时候,记录你猜想的,需要的东西。重新设计这个圈套,如果这个bug只发生在产品中,且不在你的猜想中的话,这可能是一个漫长的过程。你从日志中得到的(信息)可能不能提供解决方案,但可能给你足够的信息去优化这个日志。优化后的日志系统可能花很长时间才能被放入产品中使用。然后,你必须等待 bug 重新出现以获得更多的信息。这个循环可能会继续好几次。 + +我曾创建过的最愚蠢的偶现 bug 是在用一个函数式编程语言里为类工程做多线程实现的时候。我非常仔细地保证了函数式程序的并发估计, CPU 的充分使用(在这个例子里,是8个 CPU)。我却简单地忘记了去同步垃圾回收器。系统可能运行了很长一段时间,经常结束在我开始任何一个任务的时候,在任何能被注意到的事情出错之前。我很遗憾地承认在我理解我的错误之前,我甚至开始怀疑硬件了。 + +在工作中我们最近有这样一个偶现的 bug 让我们花了几个星期才发现。我们有一个多线程的基于 Apache™ 的 Java™web 服务器,在维护第一个页面跳转的时候,我们在四个独立线程而非页面跳转线程里,为一个小的集合执行所有的 I/O 操作。每一次跳转会产生明显的卡顿然后停止做任何有用的事情,直到几个小时后,我们的日志才让我们了解到底发生了什么。因为我们有四个线程,在一个线程内部发生这种情况并不是什么大问题,除非所有的四个线程都阻塞了。然后被这些线程排空的队列会迅速填充所有可用的内存,然后导致我们的服务器崩溃。这个 bug 花了我们一个星期去揪出这个问题,但我们仍然不知道什么导致了这个现象,不知道它什么时候会发生,甚至不知道它们阻塞的时候,线程们在干什么。 + +这表明了有关使用第三方软件的一些风险。我们在使用一段授权的代码,从文本中移除HTML标签。受它的起源的影响,我们把它叫做法国脱衣舞者。尽管我们有源代码(由衷感谢!),我们没有仔细研究它,直到查看我们服务器的日志的时候,我们最终意识到是“法国脱衣舞者”使邮件线程阻塞了。 + +这个工具在大多数时候工作得很好,除了处理一些长而不常见的文本时。在那些文本里,代码复杂度是 N 的平方或者更糟。这意味着处理时间与文本的长度的平方成正比。正式由于这些文本通常都会出现,所以我们才可以马上发现这个 bug。如果他们从来都不会出现,我们永远都不会发现这个问题。当它发生时,我们花了几个星期去最终理解并且解决了这个问题。 + +Next [如何学习设计技能](11-How-to-Learn-Design-Skills.md) diff --git a/zh/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md b/zh/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md new file mode 100644 index 0000000..8f6498d --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md @@ -0,0 +1,9 @@ +# 如何学习设计技能 +[//]: # (Version:1.0.0) +为了学习如何设计软件,你可以在导师做设计的时候,在他身边学习他的行为。然后学习精心编写过的软件片段(译者注:比如 android 系统中的谷歌官方应用源码)。在这之后,你可以读一些关于最新设计技术的书。 + +然后你必须自己动手了。从一个小的工程开始,当你最后完成时,考虑为什么这个设计失败了或成功了,你是怎样偏离你最初的设想的。然后继续去着手大一点的工程,在与其他人合作时会更有希望。设计是一种需要花很多年去学习的关于评判的事情。一个聪明的程序员可以在两个月内充分打好这种基础,然后从这里开始进步。 + +发展出你自己的风格是自然而有用的,但记住,设计是一种艺术,而不是一种技术。人们写的关于这个主题的书都有一种使得它好像是技术的既定的兴趣。不要武断对待特定的设计风格。 + +Next [如何进行实验](12-How-to-Conduct-Experiments.md) diff --git a/zh/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md b/zh/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md new file mode 100644 index 0000000..c9fedec --- /dev/null +++ b/zh/1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md @@ -0,0 +1,22 @@ +# 如何进行实验 +[//]: # (Version:1.0.0) +已故的伟大的 Edsger Dijkstra 曾经充分解释过:计算机科学不是一门实验科学[ExpCS],并且不依赖于电子计算机。当他提出这个观点时,他指的是19世纪60年代。[Knife] + +> ...危害已经出现:主题现在已经变成了“计算机科学” - 这实际上,像是把外科手术引用为“手术刀科学” - 这在人们心中深深植入了这样一个概念:计算机科学是关于机器和它们的外围设备的。 + +编程不应该是一门实验科学,但大多数职业程序员并没有保卫 Dijkstra 对于计算机科学的解释的荣耀。我们必须在实验的领域里工作,正如一部分,但非所有的物理学家做的那样。如果三十年后,编程可以在不进行任何实验的前提下进行,这将是计算机科学的一个巨大成就。 + +你需要进行的实验包括: +- 用小的例子测试系统以验证它们遵循文档,或者在没有文档时,理解它们的反应; +- 测试一些小的代码修改去验证它们是否确实修复了一个 bug; +- 由于对一个系统不完全的理解,需要在两种不同情况下测量它们的性能表现; +- 检查数据的完整性; +- 对困难的或者难以重现的 bug,收集解决方案中可能提示的统计数据。 + +我不认为在这篇文章里我可以讲述实验的设计,你会在实践中学习到这方面的知识。然而,我可以提供两点建议: + +第一,对你的假设或者你要测试的断言要非常清楚。把假设写下来也是很有用的,尤其是如果你有点迷惑或者与其他人合作时。 + +第二,你会经常发现你必须设计一系列的实验,它们中的每个都基于对最后一个实验的理解。所以,你应该设计你的实验尽量去提供最多的信息。但不幸的是,这会让实验保持简单变的困难 - 你必须通过经验来提升这种权衡的能力。 + +Next [团队技能 - 为什么评估很重要](../Team-Skills/01-Why-Estimation-is-Important.md) diff --git a/zh/1-Beginner/README.md b/zh/1-Beginner/README.md new file mode 100644 index 0000000..d5dc54c --- /dev/null +++ b/zh/1-Beginner/README.md @@ -0,0 +1,27 @@ +# 1. 入门 +[//]: # (Version:1.0.0) +- 个人技能 + - [学会 Debug](Personal-Skills/01-Learn-To-Debug.md) + - [如何通过分割问题 Debug](Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一个错误](Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日志调试](Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能问题](Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解决性能问题](Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何优化循环](Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何处理 I/O 开销](Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理内存](Personal-Skills/09-How-to-Manage-Memory.md) + - [如何处理偶现的 Bug](Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何学习设计技能](Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何进行实验](Personal-Skills/12-How-to-Conduct-Experiments.md) +- 团队技能 + - [为什么预估很重要](Team-Skills/01-Why-Estimation-is-Important.md) + - [如何预估编程时间](Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人们作为信息源](Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何优雅地写文档](Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代码上工作](Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代码控制](Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何进行单元测试](Team-Skills/08-How-to-Unit-Test.md) + - [毫无头绪?休息一下](Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何决定下班时间](Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何与不好相处的人相处](Team-Skills/11-How-to-Deal-with-Difficult-People.md) diff --git a/zh/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md b/zh/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md new file mode 100644 index 0000000..e3cdb96 --- /dev/null +++ b/zh/1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md @@ -0,0 +1,14 @@ +# 为什么评估很重要 +[//]: # (Version:1.0.0) +为了尽快获得一个可以高效使用的工作软件系统,不仅需要为开发做计划,还需要为文档,部署,市场做计划。在一个商业工程里,这还需要销售和金融计划。没有对开发时间的预测能力,是不可能高效预测以上这些东西的。 + +好的估计提供了预测能力。管理者喜欢,而且应该这么做。事实是这不可能,不论是理论上还是实践上,准确预测开发软件所消耗的时间总是被管理者所忽视。我们总是被要求做那些不可能的事情,而且我们必须诚实地面对它。不论如何,不承认这个任务的不可能性也是不诚实的,必要的时候,需要解释。对于评估来说,会产生很多沟通不畅的情况,因为人们令人吃惊地倾向于一厢情愿地认为下面这句话: +> 我估计,如果我确实理解了这个问题,我们在5周内有50%的可能完成任务(如果在此期间没有人干扰我们的话)。 + +的真实的含义是: + +> 我保证从现在开始五个星期内完成任务。 + +这个常见的解读问题需要你与你的 boss 和客户明确地讨论(就好像把他们当做傻子那样)。重新阐述你的解释,不管对你来讲它们有多么显而易见。 + +Next [如何估计编程时间](02-How-to-Estimate-Programming-Time.md) diff --git a/zh/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md b/zh/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md new file mode 100644 index 0000000..a2764bf --- /dev/null +++ b/zh/1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md @@ -0,0 +1,21 @@ +# 如何评估编程时间 +[//]: # (Version:1.0.0) +评估需要实践,也需要劳动。因为它需要花如此长的时间,以至于评估评估本身的时间可能是一个好主意,尤其是你被要求去评估一些巨大的事情。 + +当被要求评估一些比较大的事情的时候,该做的最可靠的事情是先停下来。大多数工程师是充满热情并且是渴望愉悦的,而停下来当然会让他们不开心。但对一个进行中的事情做评估一般是不准确且不可靠的。 + +停下来,使得考虑一些事情或者为任务重新定型成为可能。如果政策压力允许,这是执行评估的最准确的方式,并且它会产生确实的进度。 + +在没有时间做调查的时候,你首先应该非常清晰地建立评估的含义。首先重新阐述要评估的内容和你编写的评估的最后部分。在你准备编写评估的时候应该把这项任务分解为一个个更小的循序渐进的任务,并且使每个小任务需要的时间不超过一天(理想情况是每个任务的长度最多为一天)。最重要的事情是不要漏掉任何事情。例如,文档,测试,规划的时间,与其他小组交流的时间,还有度假时间,这些都是很重要的。如果你每天都要花时间和一些傻逼交流,在评估里为这件事情划一个明确的时间界限。这能让你的boss对于你将要花费的最少时间有了一个认识,并且可能给你更多的时间。 + +我认识一些会隐式地填充评估时间的好的程序员,但我推荐你不要这样做。填充的一个结果是你可能会耗尽别人对你的信任。例如,一个工程师可能为一个将要花费一天的工作评估为三天。这个工程师可能计划花两天去为代码写文档,或者花两天去做一些其他有用的工程。但当任务在一天内完成时,如果它在那天暴露出来的话,这是可以察觉的,并且松懈或高估的表现会出现。为你确实要做的事情做合适的剖析要好得多。如果写文档需要花两倍于编程的时间,并且评估的结果就是这样的,让这对管理者可见就能得到巨大的好处。 + +相反,显式填充。如果一个任务可能花一天,但如果你的方法没有生效,可能花十天 - 用某种方式在你的评估里记下这个情况,否则,至少为这个可能性,评估一个权重计算可能的时间。任何你可以识别和进行评估的风险因素应该在时间表里被体现。一个人不太可能在给定的任何星期都生病。但一个有很多工程师的大项目可能会有一些疾病时间,还有休假时间。或者,是否会有公司内部的强制培训研讨会的可能性呢?如果这可以预估,也把它算进来。当然,还有一些未知的未知,或者 [unk-unk](../../4-Glossary.md) 。Unk-unk 在定义上是不能被独立评估的。你可以尝试为所有 unk-unk 创建一个全局的界线,或者用你与你的 boss 交流好的其他方式去处理它们。然而,你不能让你的 boss 忘记它们的存在。在把评估变成时间表的过程中,把它们遗忘是超级容易的。 + +在一个团队环境里,你应该让任务的执行者去做这种评估,而且你们应该在团队范围内对评估的结果达成一致。人与人在技术,经验,准备和信心上都有很多的不同。当一个牛逼的程序员为他自己评估了时间,然后一些弱一点的程序员被这种评估约束时,灾难就会降临。整个团队在一个一行一行的细致的评估计划上取得的一致,阐述了团队的理解,以及允许在策略上对资源的重新分配的机会(比如,把负担从弱一点的团队成员那里移到强一点的成员那里)。 + +如果有不能评估的大风险,你应该无论如何都要提出来,这是你的责任,这让才能让管理者不会在这个问题上做承诺,以免在风险发生时让管理者难堪。这种情况下,任何需要的事情都有希望被执行来减小这个风险。 + +如果你可以说服你的公司去使用*极限编程*,你只需要评估相当小的事情,这也是更加有趣和有效率的。 + +Next [如何发现信息](03-How-to-Find-Out-Information.md) diff --git a/zh/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md b/zh/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md new file mode 100644 index 0000000..b9613fa --- /dev/null +++ b/zh/1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md @@ -0,0 +1,19 @@ +# 如何发现信息 +[//]: # (Version:1.0.0) +你所搜寻的事情的本质决定了你应该如何去寻找它。 + +如果你需要客观的而且容易辨认的*关于具体事物*的信息,例如一个软件的最新补丁版本,可以在Internet搜索,礼貌的询问很多的人,或者发起一个讨论组。不要在网上搜索任何带有观点或主观解释的东西:能够抵达真相的概率太低了。 + +如果你需要“一些主观的普遍知识”,人们对这些东西已有的思考历史,那就去图书馆吧。例如,想要了解数学,蘑菇或着神秘主义,就去图书馆吧。 + +如果你需要知道*如何做一些琐碎的事情*,找两三本关于这个主题的书,仔细阅读。你可以从网络上学到如何做好这些琐碎的事情,比如安装一个软件包。你甚至可以学到一些重要的东西,例如好的编程技术,但相比读一本纸质书的相关部分,你很容易花更多时间在搜索和对结果排序,以及评估结果的权威性。 + +如果你需要*可能没有人知道的信息*,例如,“这个新品牌的软件在海量数据的情况下能工作吗”,你仍然必须在网络和图书馆里搜索。在这些选项都完全竭尽后,你可能需要设计一个实验来搞清楚这个问题。 + +如果你需要一些考虑了某些特殊环境的观点或估值,和一个专家聊聊。例如,如果你想要知道用 Lisp 构建一个现代数据库管理系统是否是一个好主意,你应该和一个 Lisp 专家和一个数据库专家聊一聊。 + +如果你想要知道*它具体是怎样的*,比如一个还未发布的在一个特定程序上更快的算法,跟一些在这个领域工作的人聊聊。 + +如果你想要做一个*只有你自己能做的个人决定*,比如你是否应该开始某个事业,尝试把一些对这个想法有益和有害的点列出来。如果这没有什么用,做一些预测。假设你已经从各个角度研究了这个想法,并且做了所有该做的准备,在心里列举所有的后果,包括好的和坏的,但你仍可能犹豫不决。你现在应该遵循你自己内心的想法,然后让你的大脑停止思考。大多数可用的预测技术都对决定你内心一半的欲望有作用,因为它们在体现你自己完全多义和随机模式的潜意识都很有用。 + +Next [如何将人们作为信息源](04-How-to-Utilize-People-as-Information-Sources.md) diff --git a/zh/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md b/zh/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md new file mode 100644 index 0000000..73723cb --- /dev/null +++ b/zh/1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md @@ -0,0 +1,15 @@ +# 如何把人们作为信息源 +[//]: # (Version:1.0.0) +尊重其他每个人的时间,与你的时间相平衡。问别人问题比得到答案能获得更多。人们会从你的存在和倾听特定的问题从你身上学到东西。你也可以用同样的方式从别人身上学习到东西,你可能学到你正在搜寻的东西的答案。这通常比你的问题更加重要得多。 + +然而,这个问题的价值会减少你在上面做的事情。你毕竟使用了一个人拥有的最珍贵的商品:时间。交流的好处必须与代价相权衡。更进一步,特定的代价和好处在人与人之间都不一样。我强烈相信一个100人的管理者每个月应该花五分钟与他所在的组织的每个人谈话,大概是它们的时间的5%。但十分钟可能太多了,如果他们有1000个员工,5分钟也可能太多了。你与组织中每个人交谈花费的时间取决于他们的角色(而非他们的位置)。你应该和你的 boss 交谈而非和你 boss 的 boss 交谈,但你偶尔也可以和你 boss 的 boss 交谈啦。这可能不太舒服,但我相信你有责任每个月和你的上上级稍微聊聊,什么都行。 + +基本的规则是,每个与你交谈的人都能稍微受益,他们与你聊得更多,他们能获得的收益越少。你的应该给他们提供这种好处,还有得到与他们交流的好处,平衡这种好处与花费的时间。 + +尊重你自己的时间是很重要的。如果和一些人聊天,即使这会消耗他们的时间,结果会节省你很多的时间,那么你应该这样做,除非你认为他们的时间在这个因素上,对整个集体,比你的时间更加有价值。 + +一个奇怪的例子是暑期实习生。一个处于高技术含量位置的暑期实习生不能被期望去完成太多东西;他们可能会把每个人纠缠到地狱。但为什么这是被允许的呢?因为被纠缠的人从实习生身上可以接收到一些重要的东西。他们得到了一点炫耀的机会,他们可能有机会去听到一些新的思想,他们有机会可以从不同的角度去看问题。他们可能会尝试招聘这个实习生,但即使不是这样,他们也获得了很多。 + +如果你真诚地相信别人有一些东西可以告诉你,无论合适,应该询问他们的意见与智慧。这能让他们高兴并且你可以从他们身上学到一些东西,也可以教会他们一些东西。一个好的程序员不会经常需要销售副经理的建议,但如果你需要,你当然应该询问这个问题。我曾经被要求去倾听一些销售电话以便更好地理解我们的销售员工的工作。这不会耗费超过30分钟,但却让我通过这么小的付出就对公司的销售队伍有了深刻的印象。 + +Next [如何优雅地写文档](05-How-to-Document-Wisely.md) diff --git a/zh/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md b/zh/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md new file mode 100644 index 0000000..caccfbc --- /dev/null +++ b/zh/1-Beginner/Team-Skills/05-How-to-Document-Wisely.md @@ -0,0 +1,20 @@ +# 如何睿智地写文档 +[//]: # (Version:1.0.0) +人生太短,不能写没人会读的废话,如果你写了废话,没人会去读。所以好一点的文档是最好的。经理不会去理解这些东西,因为不好的文档会给他们错误的安全感以至于他们不敢依赖他们的程序员。如果一些人绝对坚持你真的在写没用的文档,就告诉他们“是的”,然后安静的找一份更好的工作。 + +没有其他事情比精确估计 把好的文档转为放松文档要求的估计 更为有效率。真相是冷酷而艰难的:文档,就像测试,会花比开发代码多几倍的时间。 + +首先,写好的文档是好的写作。我建议你找一些关于写作的事情,学习,练习他们。但即使你是一个糟糕的写手或者对你需要写文档的语言掌握不好,这条黄金规则是你真正需要的:己所不欲,勿施于人。花时间去确实地思考谁会读你的文档,他们从文档中想要获得的真正的东西是什么,并且你可以如何把这些东西交给他们。如果你这样做,你将会变成一个超过平均水平的文档编写者,和一个好的程序员。 + +当代码可以自成文档时,与提供文档给非程序员看相反,我认识的最好的程序员们有这样一个普遍的观点:编写具有自我解释功能的代码,仅在你不能通过代码清晰解释其含义的地方,才写注释。有两个好的原因:第一,任何人需要查看代码级别的文档大多数情况下都能够并且更喜欢阅读代码。不可否认的,有经验的程序员似乎比初学者更容易做到这件事,然而,更重要的是,没有文档的话,代码和文档不会是自相矛盾的。源代码最糟糕的情况下可能是错误并且令人困惑的。没有完美编写的文档,可能说谎,这可糟糕一千倍。 + +负责任的程序员也不能让这件事变得更简单些。如何写自解释的代码?那意味着什么?它意味着: + +- 编写知道别人会去阅读的代码(译者注:编写给人看的代码) +- 运用黄金法则 +- 选择直接的解决方案,即使你可以更快地获得另一个解决方案 +- 牺牲那些可能混淆代码的小的优化 +- 为读者考虑,把你珍贵的时间花在让她更加容易阅读的事情上,并且 +- 永远不要使用这样的函数名比如 `foo`,`bar`, 或 `doIt`! + +Next [如何在糟糕的代码上工作](06-How-to-Work-with-Poor-Code.md) diff --git a/zh/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md b/zh/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md new file mode 100644 index 0000000..a7ecd95 --- /dev/null +++ b/zh/1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md @@ -0,0 +1,11 @@ +# 如何在糟糕的代码上工作 +[//]: # (Version:1.0.0) +工作在别人写的糟糕的代码上是常有的事。不要把他们想得太糟,直到你用他们的鞋子走路时。他们可能被要求非常自觉地快速完成一些东西来满足时间表的压力。不管之前发生了什么,为了在不清晰的代码上工作,你必须理解它。理解它需要花费一些学习时间,你必须坚持从时间表中某些部分划出一部分时间来做这件事。为了理解它们,你必须读源代码,你可能需要在上面做一些实验。 + +即使是为你自己,编写文档也是一个好的时机,因为尝试为你的代码编写文档会强迫你从你可能没有考虑过的角度思考,并且完成的文档可能会有用。当你在做这个时,考虑重写部分或所有代码会消耗你什么东西。是否重写一部分代码事实上真的会节省时间?你重写代码后你会更信任它吗?在这里小心你的傲慢。如果你重写它,你处理它会更容易,但下一个必须阅读它的人是否真的更加容易?如果你重写了,测试的负担在哪里?重新测试的需要是否大于可能获得的好处? + +在任何对你没有编写的代码的评估中,代码的质量会影响你对风险问题的认识以及一些未知的事情。 + +铭记抽象和封装是很重要的,这两个程序员最好的工具,对糟糕的代码是特别好用的。你可能不能够重新设计一大块代码,但如果你可以为它增加一定量的抽象,你不用重新在这整团迷雾上工作就可以获一些好的设计所带来的好处。特别的,你可以尝试去隔离尤其糟糕的代码,这样他们就可以被独立重构。 + +Next [如何使用源代码控制](07-How-to-Use-Source-Code-Control.md) diff --git a/zh/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md b/zh/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md new file mode 100644 index 0000000..0d923ba --- /dev/null +++ b/zh/1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md @@ -0,0 +1,9 @@ +# 如何使用源代码控制 +[//]: # (Version:1.0.0) +源代码控制系统(又称版本控制系统)让你高效地管理工程。他们对一个人是很有用的,对一个团队是至关重要的。它们追踪不同版本里的所有改变,以至于所有代码都未曾丢失,其含义可以归属于改变。有了源代码控制系统,一个人可以自信地写一些而半途而废的代码和调试的代码,因为你修改的代码被仔细地与提交的、官方的即将与团队共享或发布的代码分割开。 + +我挺晚才开始意识到源代码控制系统的好处,但现在即使是一个人的工程,我也不能离开源代码控制系统。当你们团队在同样的代码基础上工作时,通常它们是必要的。然而,它们有另一个巨大的优点:它们鼓励我们把代码当做一个成长的有机系统。因为每个改变都会被标记为带有名字或数字的修正,一个人会开始认为软件是一种可见的一系列渐进的提升。我认为这对初学者是尤其有用的。 + +使用源代码控制系统的一个好的技术是一直保持在几天后提交更新。在提交后,一定程度上不活跃,不被调用的代码在几天内都不会完成,因此也不会对其他任何人产生任何问题。因提交错误的代码而降低你队友的开发速度是一个严重的错误,这往往是一种禁忌。 + +Next [如何进行单元测试](08-How-to-Unit-Test.md) diff --git a/zh/1-Beginner/Team-Skills/08-How-to-Unit-Test.md b/zh/1-Beginner/Team-Skills/08-How-to-Unit-Test.md new file mode 100644 index 0000000..54c105a --- /dev/null +++ b/zh/1-Beginner/Team-Skills/08-How-to-Unit-Test.md @@ -0,0 +1,9 @@ +# 如何进行单元测试 +[//]: # (Version:1.0.0) +单元测试,对独立的代码功能片段,由编写代码的团队进行测试,也是一种编码,而非与之不同的一些事情。设计代码的一部分就是设计它该如何被测试。你应该写一个测试计划,即使它只是一句话。有时候测试很简单:“这个按钮看起来好吗?”,有时候它很复杂:“这个匹配算法可以精确地返回正确的匹配结果?”。 + +无论任何可能的时候,使用断言检查以及测试驱动。这不仅能尽早发现 bug,而且在之后也很有用,让你在其他方面担心的谜题得到解决。 + +极限编程开发者广泛高效地编写单元测试,除了推荐他们的作品,我不能做更好的事情了。 + +Next [毫无头绪?休息一下](09-Take-Breaks-when-Stumped.md) diff --git a/zh/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md b/zh/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md new file mode 100644 index 0000000..c79ff59 --- /dev/null +++ b/zh/1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md @@ -0,0 +1,5 @@ +# 毫无头绪?,休息一下 +[//]: # (Version:1.0.0) +没有思路时,休息一下。我有时候没有思路时会冥思15分钟,当我回来看问题时,它就神奇地解开了。更大尺度上,一个晚上的睡眠能做到一样的事情,临时切换到其他活动上可能也会有效。 + +Next [如何决定下班时间](10-How-to-Recognize-When-to-Go-Home.md) diff --git a/zh/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md b/zh/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md new file mode 100644 index 0000000..0845f8e --- /dev/null +++ b/zh/1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md @@ -0,0 +1,15 @@ +# 如何识别下班时间 +[//]: # (Version:1.0.0) +计算机编程是一种活动也是一种文化。不幸的事实是它不是一种看重身心健康的文化。从文化/历史缘由看(例如,在机器空载的晚上工作的需要),还有因为超过市场时间的压力和程序员的缺乏,计算机程序员传统上总是过度工作。我不认为你可以相信你听到的所有故事,但我认为一周工作60小时是常见的,50小时更多的像一个最小值。这意味着实际总是比需要的时间花费得更多。这对一个好的,不仅为他们自己负责而且为他们的同事负责的程序员来说是一个严重的问题。你需要识别什么时候下班,有时候还要建议其他人回家的时间。解决这个问题的固定规则不存在,抚养一个孩子的固定规则也是,出于同样的原因---每个人都是不同的。 + +一周超过60个小时工作对我来说是非常辛苦的,我可以申请挺短的一段时间(大概是一周),有时候在我的预料中。我不知道对一个人来说一周工作超过60小时是否公平,我甚至不知道40小时是否是公平的。然而,我确定,如果你努力工作,却在你额外工作的时间里获得了很少东西,这是很愚蠢的。对我个人来说,我认为做一个懦夫不是一个程序员该做的事。遗憾的是,事实上,程序员经常*被*要求做一个懦夫来为一些人表演,例如一个经理想要给总经理留下深刻印象。程序员经常对此屈服,因为他们希望开心,并且不善拒绝,与此相反的有四道防护墙: +- 尽可能与公司里的任何人交流,这样没人可以误导总经理正在发生的事情; +- 学习明确而防御性地评估和规划,让每个人看到时间表的内容以及它的立场; +- 学会拒绝,在必要时作为一个团队拒绝,并且 +- 如果必须的话,退出团队 + +大多数程序员是好的程序员,好的程序员想要做很多东西。为了做到这点,他们需要高效管理他们的时间。从一个问题中兴奋和深陷其中都有一定量的心理惯性。许多程序员发现他们在长久不被打扰的一段时间里能够保持兴奋和集中注意力,这让他们能最好地工作。然而,人们必须睡觉,并且有其他的责任。每个人需要找到一种方式去满足他们的生物节奏和工作节奏。每个程序员需要做任何必须的事情来提供高效的工作周期,比如只参加的某些最关键的会议,以此保留一定的时间。 + +因为我有孩子,我尝试和他们在晚上相处。我自己最好的工作节奏是工作很长的一天,在办公室或办公室附近睡觉(从家到工作我需要很长的转换时间)然后足够早地回家,在我的孩子们睡觉前与他们相处。我觉得这并不舒服,但这是我可以工作的最好的妥协。如果你得了传染病,回家。如果你有自杀的想法,回家。如果你有超过几秒的凶杀的想法,回家。如果有人有严重的心理障碍或者超出心情低落的心理疾病的标志,把他送回家。如果你由于疲劳变得与平时不同地在某种程度上趋于不诚实或失望,休息一下。不要使用药物缓解疲劳。不要滥用咖啡因。 + +Next [如何与不好相处的人相处](11-How-to-Deal-with-Difficult-People.md) diff --git a/zh/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md b/zh/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md new file mode 100644 index 0000000..6d20e15 --- /dev/null +++ b/zh/1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md @@ -0,0 +1,15 @@ +# 如何与不好相处的人相处 +[//]: # (Version:1.0.0) +你可能必须和不好相处的人相处。甚至可能你本身就是一个不好相处的人。如果你是那种与同事和权威人物有许多矛盾的人,你应该珍惜这种独立所暗示的东西,但需要在不牺牲你的智力或原则的前提下提高你的人际交往能力。 + +在这方面没有什么经验,或者先前生活的行为模式在工作场合的经验不能适用的一些程序员,对这种事情会非常困扰。不好相处的人经常习惯于拒绝,并且与他人相比,他们更不容易受社交压力所影响。关键是合适地尊重他们,而非你可能想做的事,但不要充分地满足他们想要的(译者注:他们想要的往往是过分的)。 + +程序员必须作为一个团队一起工作。当分歧出现时,它必须用某种方式解决,它不能被长时间挂起。不好相处的人通常是极度聪明的,并且有一些很有用的意见可以发表。不带对这个人的偏见,倾听并理解不好相处的人是至关重要的。失败的交流通常是分歧的基础,但它有时候可以被巨大的耐心移除。尝试冷静诚恳地保持交流,并且不接受任何可能产生更大矛盾的引诱。在一个合理的尝试理解的周期后,再做决定。 + +不要让一个恶霸强迫你做你所不同意的事情。如果你是老大,做你认为最好的事情。不要为任何个人因素做出决定,并时刻准备好为你的决定做出解释。如果你是一个有着不好相处的同事的团队成员,不要让老大的决定有任何个人影响。如果没有按你的想法发展,全身心地按(已成事实的)另一种方法去做。 + +不好相处的人能够改变与进步。我曾亲眼目睹这种情况,但这很稀少。然而,每个人都有暂时的高兴与失落情绪。 + +每个程序员但尤其是领导都会面临这样一个挑战:让不好相处的人保持完全的忙碌。他们比别人更倾向于枯燥的工作,并且更能被动地忍受。 + +Next [进阶技能](../../2-Intermediate) diff --git a/zh/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md b/zh/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md new file mode 100644 index 0000000..315f40f --- /dev/null +++ b/zh/2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md @@ -0,0 +1,13 @@ +# 如何在开发质量与开发时间权衡 +[//]: # (Version:1.0.0) +软件开发总是在工程该做什么与完成工程间妥协。但你可能被要求以牺牲你的工程适用性或商业适用性的方式,去交换工程的开发速度。例如,你可能被要求做一些糟糕的软件工程实践,但这将会导致大量维护问题。 + +如果这发生了,你的首要任务是通知你的团队,然后清楚地解释降低质量的代价。在这之后,你对这个问题的理解会比你的 boss 的理解还要更清晰。明白将会失去什么以及将要得到什么,以及在这次失去的东西,能在下一轮中得到什么。在这个过程中,由一个好工程提供的可见性应该会很有用。如果用质量换时间影响了质量保证工作,(向你的 boss 和质量保证人员)指出这个问题。如果用质量换时间会导致在之后的质量保证周期中出现更多的 bug,指出来。 + +如果她仍然坚持,你应该把劣质部分隔离到特殊的你可以在下一个开发周期计划重写或优化的组件中。向你的团队解释这个问题,这样他们可以为此做些计划。 + +忍者程序员在 Slashdot 写下了这样的格言: + +> 记住,一个好的设计会被糟糕的代码实现弹回。如果好的接口和抽象在代码中到处存在,最后的重写会更加痛苦。如果写难以修复的清晰代码很困难,考虑是什么与核心设计冲突的东西导致了这个问题。 + +Next [如何管理软件依赖](02-How-to-Manage-Software-System-Dependence.md) diff --git a/zh/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md b/zh/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md new file mode 100644 index 0000000..635f956 --- /dev/null +++ b/zh/2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md @@ -0,0 +1,13 @@ +# 如何管理软件系统依赖 +[//]: # (Version:1.0.0) +现代软件系统趋向于依赖大量的非直接可控的组件。通过协同与重用,这增加了生产效率。然而,每个组件会带来一些问题: + +- 你该如何修复组件中的 bug? +- 组件限制你使用特殊的硬件或软件系统了吗? +- 如果组件完全坏掉了,你该做什么? + +某些程度上解耦组件,让它独立可以被移除,总是最好的。如果组件被证明完全不可用,你可能能够使用不同的组件,但你可能必须自己写一个组件。解耦不是可移植性,但这让移植变得简单,这大多数时候是好事。 + +拥有组件源代码可以把风险降到1/4.有了源代码,你可以更容易地评估它,调试它,找到避免踩坑的方法,并且使得修复更容易。如果你进行修复,你必须把修复的内容提交给组件的拥有者,并且让修改合并到官方发布版中,否则你将不适地必须维护一个非官方版本。 + +Next [如何判断软件是否太不成熟了](03-How-to-Decide-if-Software-is-Too-Immature.md) diff --git a/zh/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md b/zh/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md new file mode 100644 index 0000000..09e7170 --- /dev/null +++ b/zh/2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md @@ -0,0 +1,18 @@ +# 如何判断软件是否太不成熟了 +[//]: # (Version:1.0.0) +使用其他人写的软件是一种最有效率的构建一个坚实的系统的方法之一。这本不该被排斥,但与此相关的风险必须被检验。最大的一种风险在于,它通过使用变成一个可用产品成熟前的 bug 周期和与软件相关的故障时期。在你考虑将软件系统集成前,不论是你自己写的还是第三方的,考虑它是否足够成熟以使用是非常重要的。这里有十个你应该自问的相关问题: + +1. 它是蒸汽吗?(那肯定是不成熟的) +2. 有可用的懂这个软件的人吗? +3. 你是第一使用者吗? +4. 有持续使用的强烈动机吗? +5. 有维护负担吗? +6. 没有当前的维护者的话,它还能用吗? +7. 有至少和它的一半那样好的经验丰富的其他可用途径? +8. 你的团队或公司了解它吗? +9. 你的团队或公司对它满意吗? +10. 即使它不好,你可以雇人在它上面工作吗? + +对这些标准的一点考虑论证了良好构建的自由软件和开源软件在减小企业家风险上的巨大价值 + +Next [如何做一个购买或构建决定](04-How-to-Make-a-Buy-vs-Build-Decision.md) diff --git a/zh/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md b/zh/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md new file mode 100644 index 0000000..764e06f --- /dev/null +++ b/zh/2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md @@ -0,0 +1,16 @@ +# 如何做购买还是构建的决定 +[//]: # (Version:1.0.0) +一个尝试用软件完成一些任务的企业级公司或工程必须不断做所谓的 *buy vs. build* 的决定。这个问题的不幸在两个方面:似乎忽视了不必*被购买*的开源软件和自由软件。更重要的是,这可能应该被称作*获取与集成 vs. 购买与集成*决定,因为集成的代价需要被考虑。这需要商业上,管理上,工程理解上的大量结合。 + +- 你的需要与它的设计意图有多接近? +- 对于你购买的软件,你想要怎样的可移植性? +- 评估集成的代价是什么? +- 集成的代价是什么? +- 购买会增加还是减少长期维护代价? +- 构建会把你放在一个你不想要的商业位置吗? + +在你构建一些大到足够成为另一整个商品的基础的东西前请三思。这样的想法通常是乐观积极的将会对你的团队做出许多贡献的人提出来的。如果他们的想法很引人注目,你可能会想要改变你的商业计划,但不要在没有周全考虑前就投资一个比你自己的商业还大的解决方案。 + +在考虑了这些问题后,你可能应当准备两个工程计划草案,一个给购买,一个给构建。这会强迫你考虑集成代价。你也应当考虑两种措施的长期维护代价。为了评估集成代价,你必须在购买软件前对它做一个彻底的评估。如果你不能评估好它,你可以假设购买它会有一个不可预料的风险,你应该以此决定是否购买特定的产品。如果考虑后有几个购买决定,需要花一些精力去评估每个决定。 + +Next [如何专业地成长](05-How-to-Grow-Professionally.md) diff --git a/zh/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md b/zh/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md new file mode 100644 index 0000000..779f1de --- /dev/null +++ b/zh/2-Intermediate/Judgment/05-How-to-Grow-Professionally.md @@ -0,0 +1,11 @@ +# 如何专业地成长 +[//]: # (Version:1.0.0) +承担超过你的权力的责任。扮演你想要扮演的角色。对那些对更大组织的成功做出过贡献以及对你个人提供过帮助的人表示感谢与欣赏。 + +如果你想成为团队的领导,去激励与团结。如果你想成为一个经理,担起规划的责任。你通常可以在和领导或经理在一起时,舒服地完成这些事情,因为这使得他们可以抽空去承担更大的责任。如果这太多了以至于你不能尝试,一次只做一点点。 + +评估你自己。如果你想要变成一个好的程序员,询问一些你欣赏的人你怎样才能变成他们那样。你也可以问你的 boss,他可以告诉你的东西会少一些,但对你的事业会有更大的影响。 + +计划学习新技能的方式,包括琐碎的技术类型,比如学习一个新的软件系统,和困难的社交类型,像漂亮的写作,把它们集成到你的工作中。 + +Next [如何评估面试者](06-How-to-Evaluate-Interviewees.md) diff --git a/zh/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md b/zh/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md new file mode 100644 index 0000000..743bb37 --- /dev/null +++ b/zh/2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md @@ -0,0 +1,15 @@ +# 如何评估面试者 +[//]: # (Version:1.0.0) +评估可能的员工,却没有得到它应得的能量。一个糟糕的雇佣,就像糟糕的婚姻,是非常糟糕的。每个人首要的一部分精力应该投入到招聘上,尽管这很少发生。 + +有不同的面试风格。有的是折磨人的,设计用来把候选人放在巨大压力下。这是为了这样一个有用的目的:在压力下折射出性格缺陷和弱点。候选人对待面试官不会比对待他们自己更诚实,而且,人的自欺能力是令人惊奇的。 + +你应当,最少,对候选人进行两个小时的与口头考核等价的技术技能考核。实践后,你会能够快速了解他们知道什么,快速收缩他们不知道的来标明边界。面试者会尊重这件事情。我有几次听面试者说面试的质量是他们选择公司的一个动机。聪明人会因他们的技能而被雇佣,而非他们之前工作过的地方或他们上了哪个学校或者一些无关紧要的特征。 + +做这些事情,你也应当评估他们的学习能力,这比他们所知道的要更加重要得多。你也应当留心那些难以相处的人所散发出的火药味。你可能能够在面试后通过比较笔记来识别这一点,但在面试的热烈环境中这很难分辨。人们交流的能力以及与人合作的能力比在最新的编程语言上领先更为重要。 + +一个读者有“在家”测验面试的经验。这有一个优点是揭露了一些面试者能良好地自我表现但不能写代码 - 这样的人是很多的。我个人没有尝试过这种技术,但这听起来挺合适的。 + +最后,面试也是一个销售的过程。你应该把你的公司或工程销售给候选人。然而,你是在与程序员谈话,所以不要尝试改变事实。从坏的事物开始讲起,最后以好的事物作为强有力的结束。 + +Next [怎么决定什么时候使用奇妙的计算机科学](07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) diff --git a/zh/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md b/zh/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md new file mode 100644 index 0000000..92e2e94 --- /dev/null +++ b/zh/2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md @@ -0,0 +1,15 @@ +# 如何决定什么时候使用奇妙的计算机科学 +[//]: # (Version:1.0.0) +有这样一些,例如算法,数据结构,数学,还有其他极客范的大多数程序员知道但很少使用的东西。实践中,这种奇妙的东西太复杂了,通常是不需要的。例如,当你花费大多数时间在低效的数据库调用上时,提高算法是没有什么用的。不幸的大量编程由让系统相互交流以及使用非常简单的数据结构去构建漂亮的用户界面组成。 + +高科技什么时候是合适的科技?你什么时候应当打开一本书去找一些东西而非一个毫秒级算法?做这些有时候是有用的,但这需要被小心评估。 + +对于潜在的计算机技术三个最重要的考虑是: + +- 它是否充分封装所以其他低级系统风险和复杂度过量增加以及维护代价很低? +- 好处是否是令人惊奇的(例如,成熟系统的两倍或新系统的十倍?) +- 你能够高效测试和评估它吗? + +如果一个充分独立算法使用了些许奇妙的可以减少硬件消耗或增加整个系统的两倍性能表现的算法,不考虑它可能是有罪的。争论这样一个方法的一个关键是,证明风险确实是相当的低,因为目标技术可能被充分研究过了,唯一的话题是集成的风险。在这里一个程序员的经验和评估能够真的协同奇妙的算法让集成变得容易。 + +Next [如何与非工程师交谈](08-How-to-Talk-to-Non-Engineers.md) diff --git a/zh/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md b/zh/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md new file mode 100644 index 0000000..d336760 --- /dev/null +++ b/zh/2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md @@ -0,0 +1,19 @@ +# 如何与非工程师交谈 +[//]: # (Version:1.0.0) +工程师和程序员(尤其是)通常被主流文化认为与他人不同。这意味着其他人与我们不同。与非工程师交流时,这是值得记在心里的,你应该时刻去理解观众。 + +非工程师聪明,但在创造技术类的东西不像我们那样踏实。我们制造东西。他们销售,处理,统计,管理,但他们在制造上不是专家。他们不像工程师那样擅长团队合作(毫无疑问会有例外。)他们的社交技能在非团队环境里通常像工程师那样,甚至比工程师要好,但他们的工作不总要求他们像我们那样进行亲密,珍贵的交流,以及细致的任务划分。 + +非工程师可能太渴望以至于不能被取悦和与你亲近,他们可能在不是真的对你满意的时候却对你说“是”,或者是因为他们有点怕你,然后不会对你说实话。 + +非工程师可以理解技术的东西,但他们不会做那件甚至对我们来讲都很困难的事情 - 技术评审。他们确实理解技术是如何工作的,但他们不能理解为什么一个特定的方法需要花三个月而另一种方法要花三天。(毕竟,程序员对这种估计也感到事多得可怕。)这相当于一个巨大的和他们协作的机会。 + +与你的团队交谈时,你会不假思索地使用某种程度上的简略表达方式,一种简单的语言更有效率,因为你通常对技术或者特别是你的产品会有许多的共享经验。对于那些没有这些共享经验的人不使用简略表达方式是需要作出一些努力的,特别是你团队内部的人员也在场的时候。这些简略的词汇会让你与那些没有分享到相关经验的人之间构建出一道墙,甚至更糟的是,浪费着他们的时间。 + +与你的团队一起,基本的假设和目标不需要经常重申,大多数谈话集中于细节。与外人一起,就是另一回事了。他们可能不理解你认为理所当然的东西。由于你把这当做理所当然,并且没有重申它们,使得你们的谈话陷入这样一种情况:你可能认为你们相互理解,但事实上有一个巨大的误解。你应当假设你会有错误的交流,并且仔细观察去找出这样的误解。试着总结或将你说的东西分点,来确保他们能够理解。如果你有机会经常与他们见面,花一点时间询问你是否在有效地交流,以及你可以怎样把它做得更好。如果交流有问题,在对他们失望前,寻找方法去提高你自己的实践。 + +我喜欢与非工程师工作。这提供了绝大的机会来学习与传授。你可以经常由实例得到关于你的交流的阐述的指引。工程师被训练于从混乱中梳理秩序,从困惑中得到解释,非工程师会因此喜欢我们。因为我们有技术评审,并且通常可以理解商业话题,我们经常可以发现一个简单的方法来解决问题。 + +很多时候非工程师会出于好意以及一种正确做事情的欲望去规划他们认为会让我们更容易的事情,事实上存在一个仅能通过借助你的技术评审协助外人的观点看到的好得多的方法。我个人喜欢极限编程因为它处理了这种低效,通过与快速评估相结合,使得发现成本与好处最佳结合的方法更加容易。 + +Next [高级技能](../../3-Advanced) diff --git a/zh/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md b/zh/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md new file mode 100644 index 0000000..827ee3a --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md @@ -0,0 +1,14 @@ +# 如何保持活力 +[//]: # (Version:1.0.0) +创建美丽,有用,聪明的东西的欲望能高度调动程序员的积极性。这是奇妙而令人惊奇的。这种欲望对程序员既不特殊也不普遍,但在程序员中,它是如此强烈而普遍以至于它把程序员与其他角色的人们分割开来。 + +这有一个现实而重要的推论。如果当程序员被要求做一些既不美丽,也没有用,也不漂亮的事情,他们会斗志低落。虽然可以通过做丑陋的,愚蠢的,无聊的东西赚很多的钱,但最后,乐趣才会为公司赚最多的钱。 + +很明显,有一些完全由动机技术组织起来的工业适用这里的情况。这些我可以识别的特定的编程中的事情有: +- 为工作使用最好的语言 +- 寻找机会去使用新技术,新语言,新科技 +- 尝试在每个工程里学习或教授一些东西,即使很小 + +最后,可能的话,估量个人激励的东西对你工作的影响。例如,修复 bug 时,数一数我完全不感兴趣的 bug 的数目,因为这和仍然存在的 bug 数目是独立的,并且这也是影响我对公司的顾客的增值的最小的可能方式。把每个 bug 和一个高兴的顾客关联起来,*是*对我个人的激励。 + +Next [如何被广泛信任](02-How-to-be-Widely-Trusted.md) diff --git a/zh/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md b/zh/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md new file mode 100644 index 0000000..14b5240 --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md @@ -0,0 +1,7 @@ +# 如何被广泛信任 +[//]: # (Version:1.0.0) +值得信任,才能被信任。你也应该让别人了解你。如果没人了解你,没人会为你投票。跟你亲近的人一起,比如队友,这应该不是一个问题。对你部门或团队以外的人,你通过责任和博知建立信任。有时有人会滥用信任,并要求无理由的赞同。不要害怕,解释因这种赞同会让你必须放弃什么。 + +不要不懂装懂。与队友以外的人一起时,你必须清除地区分“当下在我脑子里不懂的东西”以及“我曾经没有认识到的东西”。 + +Next [如何在时间和空间权衡](03-How-to-Tradeoff-Time-vs-Space.md) diff --git a/zh/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md b/zh/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md new file mode 100644 index 0000000..6b309ed --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md @@ -0,0 +1,15 @@ +# 如何在时间与空间权衡 +[//]: # (Version:1.0.0) +没有上过大学的话,你也可以成为一个好的程序员,但你不知道基本的计算复杂度理论的话,你不可能成为一个好的进阶程序员。你不需要知道‘O’的定义,但我个人认为你应该理解‘常量时间’,‘nlogn’,'n²'的区别。你可能可以不靠这方面的知识,凭直觉知道如何在时间和空间之间权衡,但没有这种知识,你将不会有一个和你同事交流的稳固基础。 + +在设计或理解算法的过程中,算法花费的时间有时候是一个以输入量为自变量的函数。当这种情况发生时,如果运行时间与输入量的对数的 n 倍成正比,我们可以说一个算法的最坏/期望/最好情况运行时间是'nlogn',这个定义和阐述的方式也可以被应用在数据结构占用的空间上。 + +对我来时候,计算复杂度理论是美妙的,并且与物理学一样意义深远,并且可能还有很长的路要走! + +时间(处理器周期)和空间(内存)可以相互交易。工程是关于妥协的,这就是一个好的例子。它并不总是有条理的,然而,编码一些东西时更加紧凑可以节省空间,但要以解码时花费更多的处理时间为代价。你可以通过缓存节省时间,也就是,花费空间去存储某些东西的一个本地副本,但要以维持缓存的一致性为代价。你偶尔可以通过把更多信息放在一个数据结构里来节省时间。这通常只会有较小的空间占用,但可能会使算法复杂化。 + +提高时间空间转换经常把它们中的一个或另一个戏剧性地改变。然而,在你开始做这个工作前,你应该问你自己,你将要优化的是否是最需要优化的?研究算法是有趣的,但你不能让这遮蔽了你的双眼让你看不到这样一个冷酷的事实:优化一些不是问题的问题将不会带来任何明显的区别,但却会造成测试的负担。 + +现代计算机内存越来越便宜,因为不像处理器时间,你在达到边界前你不能看见它,但这种失败是灾难性的。使用内存也有隐藏的代价,比如你影响了其他需要被保留的程序,以及你分配和释放内存的时间。在你想要花更多空间去换取速度之前,请仔细考虑这一点。 + +Next [如何进行压力测试](04-How-to-Stress-Test.md) diff --git a/zh/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md b/zh/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md new file mode 100644 index 0000000..888861a --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md @@ -0,0 +1,17 @@ +# 如何进行压力测试 +[//]: # (Version:1.0.0) +压力测试很有趣,一开始好像压测的目的是找出系统在负载下能不能工作。现实中,系统在负载下确实能工作,但在负载足够重的某些情况下不能工作。我把这叫做*碰壁*或*撞响*[1]。可能会有例外,但大多数情况下会有这么一堵“墙”。压测的目的是为了指出墙在哪里,然后弄清楚怎么把墙移得更远些。 + +压测计划需要在工程的早期就规划好,因为它经常有助于弄清楚到底什么是被期望的。两秒的网页请求是一个悲伤的失败还是一个了不起的成功?500个并发用户是否足够?这,当然,视情况而定,但一个人在设计系统时就应该知道满足需求的答案。压测需要足够好地为现实建模,使之足够有用。非常容易地模拟500个不稳定并且不可预测的人并行使用系统不是真的可能的,但我们可以至少创造500个模拟(用户),然后尝试模拟他们可能做的部分事情。 + +在压测中,从轻负载开始,然后为系统在一些维度上增加复杂 - 比如输入频率和输入规模 - 直到你抵达那堵墙。如果墙太近了以至于不能满足你的需要,弄明白哪个资源是瓶颈(这通常是那个主要的资源)。它是内存?处理器?I/O?网络带宽?还是数据连接?然后弄明白你可以怎么移动那堵墙。记录下移动墙的那个要素,也就是增加了系统可以处理的负载的那个要素,它可能不能真正在低负载系统下产生危害。但通常重负载下的表现比轻负载下更重要。 + +你必须能够观察几个不同维度,以此来为之构建一个思维模型;单一的技术是不够的。例如,日志经常是给出系统中两个事件间的挂钟时间的好主意。但除非仔细构建,日志不会给出内存使用的可见性甚至是数据结构的大小。相似的,在现代系统里,大量电脑和许多软件系统是合作的。特别是在你碰到那堵墙时(也就是,表现与输入不成线性比例时),这些软件系统可能成为瓶颈。对这些系统的透视力,甚至仅仅对所有参与工作的机器的处理器做测量,都可能是非常有帮助的。 + +意识到墙在哪里的关键不仅是移动这堵墙,而且也是提供对其的预测能力。这样公司可以得到更高效的管理。 + +--- + +[1] "撞响" + +Next [如何在简洁与抽象间平衡](05-How-to-Balance-Brevity-and-Abstraction.md) diff --git a/zh/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md b/zh/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md new file mode 100644 index 0000000..183c6e6 --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md @@ -0,0 +1,9 @@ +# 如何在简洁与抽象间平衡 +[//]: # (Version:1.0.0) +抽象是编程的关键。你应该仔细选择你需要抽象的程度。充满活力的初学者经常创建许多没有什么用的抽象。一个标识是,你是否创建了这样一个类,不包含任何代码并且没有真的做什么事情,除了抽象一些东西。这种抽象是可以理解的,但代码的简洁性的价值必须与代码的抽象价值相权衡。有时候,我们可以看到一种热情的理想主义者犯的错误:在工程的一开始,定义了一大堆的看起来抽象得很美的类,然后他会推测说它们可以处理每一个可能出现的情况。随着项目推进及琐事掺杂进来,这些代码本身变得混乱了。函数体比他们本来该有的样子还要长。空的类是一种写文档的负担,在压力之下,它们会被忽略。如果让花在抽象上的精力去保持其简短,最后的结果应该会更好。这是一种*推测编程*的形式。我强烈推荐 PAUL gRAHAM[PGSite] 的这篇文章 ['Succinctness is Power' by Paul Graham](http://www.paulgraham.com/power.html)。 + +有这样一种关于*信息封装*和*面向对象编程*的有用技能,但有时候它们被带远了。这些技术让一个人抽象地编码并预计变数。然而,我个人认为,你不应该写太多推测性的代码。例如,在一个对象里用增量器和访问器隐藏一个整数变量是一种可接受的风格,这样变量本身就没有暴露,仅仅暴露了很少的关于它的接口。这确实允许了变量的实现的改变不影响调用代码,并且可能对一个必须提供一个稳定 API 的库编写者是合适的。我不认为这种好处会超过其冗长的代价,特别是当我的团队拥有调用代码并因此可以把调用器重构为比原来的更容易时。四到五行多余的代码会是这种推测性好处的沉重代价。 + +可移植性也有类似的问题。代码是否应当可移植到不同的电脑,编译器,软件系统或平台?还是简单地传输?我认为,不可移植,短而简单传输的代码比长而可移植的代码要好。把不可移植代码限制在特定的领域是一个想对轻松而且无疑是好的主意。比如一个使用了特定 DBMS 的数据库查询的类。 + +Next [如何学习新技能](06-How-to-Learn-New-Skills.md) diff --git a/zh/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md b/zh/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md new file mode 100644 index 0000000..b81efbc --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md @@ -0,0 +1,13 @@ +# 如何学习新技能 +[//]: # (Version:1.0.0) +学习新技能,尤其是非技术类,是最大的一种乐趣。大多数公司会更加有斗志如果它们明白这对程序员来说是多大的激励。 + +人类通过*做*来学。读书和上课是有用的。但你对一个从不写程序的程序员会有任何敬意吗?学习任何技能,你应该把自己放在一个可以练习技能的宽容的位置。学习一个新的编程语言时,在你必须做一个大工程前,试着用它做一个小的工程。学习管理软件项目时,先试着管理一个小的工程。 + +一个好的导师不是你做事情的替代品,而是比一本书更好的存在。你可以提供什么给一个潜在的导师,作为他的知识的交换?至少,你应该努力学习这样他们的时间才不会被浪费。 + +试着让你的 boss 给你正规的训练,但必须知道,这通常并不会比把相同量的时间花在用你想学的技能来简单玩耍要好上多少。然而,要求训练比在我们不完美世界里的玩耍时间要容易得多,尽管大量正规训练只是在课程上睡觉,等着晚餐聚会。 + +如果你领导团队,需要知道他们是怎么学习的,并且通过给他们安排适量的和他们感兴趣的技能的工程来锻炼他们。不要忘记程序员最重要的技能不是技术。让你的团队成员有一个机会去玩,锻炼勇气,诚实,以及交流。 + +Next [学会打字](07-Learn-to-Type.md) diff --git a/zh/2-Intermediate/Personal-Skills/07-Learn-to-Type.md b/zh/2-Intermediate/Personal-Skills/07-Learn-to-Type.md new file mode 100644 index 0000000..d5e032a --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/07-Learn-to-Type.md @@ -0,0 +1,5 @@ +# 学会打字 +[//]: # (Version:1.0.0) +学会盲打。这是一个进阶技能,因为写代码是如此困难以至于你的打字速度是不太相关的,并且不能削减写代码花费的时间,不管你打字有多好。但是,到了你是一个进阶程序员的时候,你可能花费很多时间在用自然语言给你的同事或他人写东西上。这是对你的责任感是一种有趣的测试,学习这样的东西需要专注的时间,但不怎么有趣。有这样一个传说,当 Michael Tiemann 在 MCC 的时候,人们会站在他的门外面倾听他击键的声音,这种声音是如此的急促以至于难以分辨。 + +Next [如何做集成测试](08-How-to-Do-Integration-Testing.md) diff --git a/zh/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md b/zh/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md new file mode 100644 index 0000000..b12a93d --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md @@ -0,0 +1,7 @@ +# 如何做集成测试 +[//]: # (Version:1.0.0) +集成测试是对已经进行单元测试的各个部分的一种整合测试。集成是昂贵的,并且它出现在测试中。你必须把这个考虑到你的预计和时间表里。 + +理想情况下,你应该这样组织一个项目,使得最后没有一个阶段是必须通过显式集成来进行的。这比在项目过程中,随着事情完成逐渐集成事情要好得多。如果这是不可避免的,请仔细评估。 + +Next [交流语言](09-Communication-Languages.md) diff --git a/zh/2-Intermediate/Personal-Skills/09-Communication-Languages.md b/zh/2-Intermediate/Personal-Skills/09-Communication-Languages.md new file mode 100644 index 0000000..e442315 --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/09-Communication-Languages.md @@ -0,0 +1,11 @@ +# 交流语言 +[//]: # (Version:1.0.0) +在语法系统里,有一些正式定义的,非编程语言但是*交流语言*的语言,它们为促进交流而非标准而特别设计。2003年,最重要的这种语言有: UML, XML, SQL。你应该熟悉这些东西,这样你就可以很好地交流并且决定什么时候去使用它们。 + +UML 是一个丰富的用图表描述设计的正式系统。它的美丽之处在于它既虚拟又正式,在作者和观众都了解 UML 的前提下,可以容纳大量的信息。你需要了解它,因为设计有时候就是用这种方式交流的。有一些非常有用的工具可以让制作 UML 图看起来非常专业。在很多情况下,UML 太正式了,我自己会使用更简单的*箱子与箭头*的风格来设计图标。但我非常确定 UML 对你来说至少跟学习拉丁语一样有用(译者注:国外拉丁语使用很广泛)。 + +XML 是设计新标准的标准。这不是一个数据间交换的问题的解决方案,尽管你有时候会看到它在这种情况下出现。更进一步,它是一种受欢迎的对大部分数据交换的无聊部分的自动化,也就是,把表现结构化为线性序列,还有将其转回一个结构。它提供了一些漂亮的类型和正确性检查,尽管,又一次,实践中你可能需要的只是其中的一部分。 + +SQL 是一种非常有力而丰富的数据查询和操作语言,而非一种编程语言。它有许多种类,典型地依赖于产品,但这没有标准核心那么重要。SQL 是关系数据库的*巧舌弗兰卡*。你可能可以也可能不可以在任何领域从对关系数据库的理解中受益,但你必须对它们和 SQL 的语法和含义有基本的理解。 + +Next [重型工具](10-Heavy-Tools.md) diff --git a/zh/2-Intermediate/Personal-Skills/10-Heavy-Tools.md b/zh/2-Intermediate/Personal-Skills/10-Heavy-Tools.md new file mode 100644 index 0000000..3843661 --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/10-Heavy-Tools.md @@ -0,0 +1,14 @@ +# 重型工具 +[//]: # (Version:1.0.0) +随着我们的科技文化的进步,软件技术从不可想象,到研究,到新的产品,到标准化产品,到广泛可用和廉价产品。这些重型工具可以拉动很大的负载,但可能是进阶的,并且需要花大量投资去理解。进阶程序员必须知道如何管理它们以及它们什么时候应该被使用或考虑。 + +现在在我看来,一些最好的重型工具是: + +- 关系数据库; +- 全文搜索引擎; +- 数学库; +- OpenGL; +- XML 解析器; +- 电子表格。 + +Next [如何分析数据](11-How-to-analyze-data.md) diff --git a/zh/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md b/zh/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md new file mode 100644 index 0000000..2f970d8 --- /dev/null +++ b/zh/2-Intermediate/Personal-Skills/11-How-to-analyze-data.md @@ -0,0 +1,17 @@ +# 如何分析数据 +[//]: # (Version:1.0.0) +当你检查一个商业活动并且发现了把它转换为软件应用程序的需求时,数据分析是软件开发早期的一个过程。这是一个官方的定义,当你,一个程序员,应该集中注意力在写别人设计的东西的代码时,这可能会让你相信数据分析是一种更应该归入系统分析的行为。如果我们严格遵循软件工程范式,这可能是正确的。有经验的程序员会成为设计者,最尖锐的设计者变成商业分析师,因此被冠名去思考所有数据需要,并且给你充分定义的任务去执行。这不完全是对的,因为数据是每种编程活动的核心。不管你在你的程序里做什么,你不是在移动数据就是在修改数据。商业分析师分析的是更大尺度上的需要,软件设计者更加压榨这个比例以至于,当问题在你的桌上落地时,好像你需要做的所有事情是应用聪明的算法,开始移动已经存在的数据。 + +不是这样的。 + +不管你开始观察它的是哪个阶段,数据是一个良好设计的应用程序主要考虑的因素,如果你仔细观察一个数据分析师是怎么从客户请求中获取需求的,你会意识到,数据扮演了一个基本的角色。分析师创建了所谓的数据流表,所有的数据源被标记出来,信息的流动被塑造出来。清晰定义了什么数据应该是系统的一部分,设计师将会用数据关系,数据交换协议,文件格式的形式塑造数据源,这样任务就准备好传递给程序员了。然而,这个过程还没结束,因为你(程序员)在这个周密的数据提取过程后,需要分析数据以用最好的可能方式表现任务。你的任务的底线是 Niklaus Wirth,多种语言之父,的金句:“算法+数据结构=程序”。这永远不是一个独立的自嗨的算法。每个算法都至少被设计去做一些至少与一段数据相关的事情。 + +因此,由于算法不会在真空中滚动轮子,你需要分析其他人已经为你标记好的数据和必须写入代码的必要的数据。 +一个小例子会使得事情更清楚。实现一个图书馆的搜索程序时,通过你的说明书,用户用类型/作者标题/出版社/出版年份/页数来选择书本。你的程序的中级目标是提供一个合法的 SQL 语句去搜索后端数据库。基于这些需要,你有几个选择:按顺序检查每个控制条件,使用一个 switch 语句,或者几个 if 语句;用一个数据控制数组,把它们与一个事件驱动引擎相连。 + +如果你的需求也包括提高查询性能,通过确认每个项在一个特殊顺序里,你可能考虑使用组件树去构建你的 SQL 语句。正如你可以看到的,算法的选择依赖于你决定使用或将要创建的数据。这样的决定产生高效算法和糟糕算法间的区别。 +然而,效率不是唯一要考虑的因素。你可能在你的代码里使用一打命名变量,让它变得尽可能高效。但这样一段代码可能不能容易地维护。可能为你的变量选择一种合适的容器可以保持相同的速度,此外,在的你同事明年看代码的时候,让他们能够更好地理解代码。更多的,选择一个良好设计的数据结构可能允许他们在不重写代码的前提下,拓展你的代码的功能。长久看来,你对数据的选择决定了你结束代码的工作后,它能工作多久。 + +让我给你看另一个例子,只是一些思想粮食,让我们假设你的任务是找到字典里超过三位的同字异构词(一个异构词必须在同样的字典里有另一个词)。如果你把这当做一个计算任务,你将会结束于无尽的,尝试找出每个单词的所有组合,然后拿它跟列表里的所有其他单词比较,这样一个无尽的努力中。然而,如果你分析了手头的数据,你会意识到,每个单词可能被一个包含这个词本身以及用它的字母作为 ID 的排序数组的记录所代表,这个蛮力算法可能需要运行几天,而小的那个算法只是一件几秒的事。下次面对一个棘手的问题时,记住这个例子。 + +Next [团队技能 - 如何管理开发时间](../Team-Skills/01-How-to-Manage-Development-Time.md) diff --git a/zh/2-Intermediate/README.md b/zh/2-Intermediate/README.md new file mode 100644 index 0000000..32ad0d6 --- /dev/null +++ b/zh/2-Intermediate/README.md @@ -0,0 +1,29 @@ +# 2. 进阶 +[//]: # (Version:1.0.0) +- 个人技能 + - [如何保持活力](Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被广泛信任](Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在时间和空间之间该如何权衡](Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何进行压力测试](Personal-Skills/04-How-to-Stress-Test.md) + - [如何权衡简洁与抽象](Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何学习新技能](Personal-Skills/06-How-to-Learn-New-Skills.md) + - [学会打字](Personal-Skills/07-Learn-to-Type.md) + - [如何进行集成测试](Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流语言](Personal-Skills/09-Communication-Languages.md) + - [重型工具](Personal-Skills/10-Heavy-Tools.md) + - [如何分析数据](Personal-Skills/11-How-to-analyze-data.md) +- 团队技能 + - [如何管理开发时间](Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方软件风险](Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理咨询](Team-Skills/03-How-to-Manage-Consultants.md) + - [如何适度交流](Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言异议以及如何避免](Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) +- 评判 + - [如何权衡开发质量与开发时间](Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理软件系统依赖](Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何评判软件是否太不成熟了](Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何决定购买还是构建](Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何专业地成长](Judgment/05-How-to-Grow-Professionally.md) + - [如何评估面试者](Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何决定什么时候使用奇妙的计算机科学](Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何与非工程师交谈](Judgment/08-How-to-Talk-to-Non-Engineers.md) diff --git a/zh/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md b/zh/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md new file mode 100644 index 0000000..66d67d9 --- /dev/null +++ b/zh/2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md @@ -0,0 +1,11 @@ +# 如何管理开发时间 +[//]: # (Version:1.0.0) +管理开发时间,需要维护一个简明且实时更新的计划。一个工程计划是一个估计,一个时间表,一系列取得进步的里程碑,还有对你的团队或者你的时间在每个任务的估计和安排。这也应该包括你需要记得去做的其他事,比如与质量保障人员见面,准备文档,或者订购设备。如果你在一个团队里,工程计划会是一个共同承认的协议,不论是在开始,还是进行的过程中。 + +工程计划存在的意义是帮助做出决定,而非展示你是如何组织的。如果一个工程计划太长或者不是最新的,它对做出决定将是无用的。现实中,这些决定通常是关于独立的个人的。计划和你的判断让你决定你是否应当把任务从一个人身上移到另一个人身上。里程碑标识了你的进展。如果你有一个奇妙的工程规划工具,不要被为工程创建一个表面巨大设计(Big Design Up Front)所迷惑,但可以用它保持清晰和实时性。 + +如果你没有一个里程碑,你应该采取即时的行动,比如通知你的 boss 工程已经滑过的部分中进度的完成。这种估计和时间表可能不会在开始时很完美,这会产生这样一种幻觉,你能够填补工程的上一个部分中错过的日志。你可以。但这很可能是因为你低估了那个部分或者高估了一部分。所以工程进度的完成已经滑过了,不管你是否喜欢。 + +确保你的计划包括了:内部团队会议,写代码,文档,规划周期活动,集成测试,处理外部关系,疾病,休假,已有工程维护,还有开发环境维护。工程计划可以作为一种为局外人或你的 boss 准备的关于你或你的团队正在做的事情的视图。因为如此,所以它应该是短且及时更新的。 + +Next [如何管理第三方软件危机](02-How-to-Manage-Third-Party-Software-Risks.md) diff --git a/zh/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md b/zh/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md new file mode 100644 index 0000000..2518db2 --- /dev/null +++ b/zh/2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md @@ -0,0 +1,11 @@ +# 如何管理第三方软件危机 +[//]: # (Version:1.0.0) +一个工程通常依赖于其不能控制的组织所生产的软件,第三方软件危机是每个相关的人都必须意识到的。 + +永远也不要把希望放在*蒸汽*上面。蒸汽是任何所谓的尚未可用然而声称可用的软件。这是最确定的一种破产的方式。仅仅怀疑一个软件公司在某个日期对于某个软件产品的某个特性的承诺是不明智的。更明智的做法是完全忽略它,并且忘记你曾听说过这种事。不要在你的公司使用的任何文档里写下这些东西。 + +如果一个第三方软件不是蒸汽,它仍然是有风险的,但至少它是一个可以处理的蒸汽。如果你正在考虑使用第三方软件, 你应该早点投入一点精力去评估它。人们可能没听说过,评估三个产品的适合性要花两个星期还是两个月,但这必须尽可能及早做。如果没有合适的评估,集成的代价就不能被准确计算。 + +理解已有的为某个特殊目的的第三方软件的适用性是非常见仁见智的东西。这是非常客观的,并且通常住在专家心里。如果你发现了那些专家,你可以节省很多时间。很多时候,一个工程会如此完全地依赖于第三方软件,以至于如果集成失败了,工程就失败了。像时间表里写的那样清晰地表达了危机。如果危机不能被尽早消除,试着订一个为意外准备的计划,比如可用的第二方案,或者自己写下功能点的能力。永远不要让时间表依赖于蒸汽。 + +Next [如何管理咨询师](03-How-to-Manage-Consultants.md) diff --git a/zh/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md b/zh/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md new file mode 100644 index 0000000..bd58e19 --- /dev/null +++ b/zh/2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md @@ -0,0 +1,9 @@ +# 如何管理咨询师 +[//]: # (Version:1.0.0) +使用咨询师,但不要依赖他们。他们是神奇的人,非常值得尊敬。因为他们看过许多不同的工程,他们通常比你知道更多具体技术,甚至是编程技术。最好的使用他们的方式是像家教那样用例子教学。 + +然而,他们通常不能像正常员工那样用相同的感觉融入团队,可能仅仅是因为你没有足够的时间去学习他们的优点和缺点。他们的工资更低。他们更容易离开。如果公司做得好,他们可能得到的更少。有些可能是好的,有些可能与平均水平一致,有些可能挺糟糕,但希望你对咨询师的选择不会像你对雇员的选择那样仔细,这样你会获得更多不好的咨询师。 + +如果咨询师要写代码,你必须在你使用它们前仔细 review。有着大段带风险而没有被 review 的代码,会让你完成不了工程。事实上这对所有的团队成员都是成立的,但你通常有更多与你接近的团队成员的知识。 + +Next [如何适量交流](04-How-to-Communicate-the-Right-Amount.md) diff --git a/zh/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md b/zh/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md new file mode 100644 index 0000000..9141eed --- /dev/null +++ b/zh/2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md @@ -0,0 +1,7 @@ +# 如何适量交流 +[//]: # (Version:1.0.0) +仔细考虑会议的代价:这花费了*随参与者数量倍增的时间*。会议有时候是必要的,但越小越好。小会议的交流质量更好,过度浪费的时间更少。如果一个人在会议感到厌烦,把这当做会议应该更小的标识。 + +非正式交流值得做任何事情去鼓励。更多有用的沟通工作在同事间的午饭可以进行,而非其他的时间。许多公司没有意识到或者不支持这一点,这是一种遗憾。 + +Next [如何直言异议以及如何避免](05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) diff --git a/zh/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md b/zh/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md new file mode 100644 index 0000000..11a2e85 --- /dev/null +++ b/zh/2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md @@ -0,0 +1,11 @@ +# 如何直言异议以及如何避免 +[//]: # (Version:1.0.0) +异议是一个做出好决定的绝佳机会,但这需要被谨慎处理。你可能会觉得你充分的表达了你的想法,并且在决定做出前,你的意见已经被听取。这种情况下,没有什么可以再说的,你应该决定你是否要支持这个决定,即使你不同意它。如果你可以在自己不同意的情况下,支持这个决定,就这样说实话。这展示了你是多么有价值,因为你是独立的,不是一个唯唯诺诺之人,同时是一个尊重决定的团队成员。 + +有时候一个你不同意的决定,会在决策者没有充分听取你的观点前做出。你应该在公司和集体的基础上评估是否应该提出这个话题。如果在你看来这只是一个小错误,这可能不值得重新考虑。如果在你看来这是一个大错,你当然必须提出异议。 + +通常,这不是一个问题。在一些充满压力的环境下,在一些个人因素下,这会导致事情个人化。例如,一些非常牛逼的程序员缺乏在有好的理由认为一件东西是错的情况下去挑战决议的信心。在最糟的情况下,决策者是不可靠的,并会把这变成一个对权威的挑战。最好记住,这种情况下,人们会用他们大脑中爬虫动物的部分来做出反应。你应该私下提出你的争议,然后尝试展示新的知识是如何改变决议做出的基础的。 + +不管决议是否被推翻,你必须记住你永远不能说出“我的话撂这了,我早就这样告诉你了”这样的话,因为这个决定已经得到了充分探讨。 + +Next [判断 - 如何在开发质量和开发时间间权衡](../Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) diff --git a/zh/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md b/zh/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md new file mode 100644 index 0000000..6fe2a41 --- /dev/null +++ b/zh/3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md @@ -0,0 +1,11 @@ +# 如何与时间压力做斗争 +[//]: # (Version:1.0.0) +发布压力是快速推出好产品的压力。这是好的,因为它反映了市场事实,并且在某个意义上是健康的。时间压力是迫使一个产品更快地推出的压力,这是浪费的,不健康的,并且太普遍了。 + +时间压力的存在是有原因的。给程序员任务的人们没有完全尊重我们的强烈的工作道德以及作为一个程序员的乐趣。可能是因为他们把自己的习惯投射到我们身上,他们相信,要求更快会让我们更加努力工作,使得工程更快完成。这可能确实是对的,但效果很小,损害很大。另外,他们看不到生产软件真实需要的东西。他们看不到,也不能够自己创造,他们能做的唯一事情就是看着发布的压力,然后烦程序员。 + +与时间压力斗争的方法是简单地把它当做发布压力,实现的方法是让可用劳力与产品间的关系变得透明。提供一个诚实,细致,大部分可理解的对所有相关劳力的估计,是一种最好的实现方式。允许做出好的管理决定以权衡可能的功能也是一个附加的好处。 + +必须清楚解释的关键是,预算是一种几乎不可压缩的液体。就像你不能把水放进充满的瓶子里,你不能往充满的时间中填入更多任务。某种意义上,程序员永远不会拒绝,但更喜欢说“得到你想要的东西,你会失去什么?”,做出清晰的预算的效果将会是增加对程序员的尊敬。这也是其专业行为的一种表现。程序员的努力工作会被看到。很明显,设置一个不现实的时间表对每个人都是痛苦的。程序员不能被欺骗。要求他们做一些不现实的东西是对他们的不尊重和不道德。极限编程放大了这个问题,并且围绕它构建了一套流程,我希望每个读者能足够幸运去使用它。 + +Next [如何理解用户](02-How-to-Understand-the-User.md) diff --git a/zh/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md b/zh/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md new file mode 100644 index 0000000..d2c7b33 --- /dev/null +++ b/zh/3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md @@ -0,0 +1,17 @@ +# 如何理解用户 +[//]: # (Version:1.0.0) +理解用户以及帮助你的 boss 理解用户是你的责任。因为用户没有像你一样密切地与你的产品的制造产生联系,他们的表现有点不同: + +- 用户通常会做出简短的判断 +- 用户有他们自己的工作,他们主要会思考你的产品中小的改进,而非大的改进 +- 用户看不到你的产品的整个用户画像 + +你的责任是找出他们真实需要的东西,而非他们说他们需要的东西,然而,更好的是在你开始前给他们提出建议,并且让他们认同你的建议就是他们想要的,但他们也可能没有做这种事的愿景。你对你自己的主意的信心是要看情况的。你必须同时与自大和错误的谦逊做斗争去找出什么是人们真实想要的。这两种人,或者同一个人身上两种思维模式,一同和谐工作会给出最好的机会来给出正确的愿景。 + +你在用户身上花费的时间越多,你就越能更好地理解什么能够真正地成功。你应当尝试在你的用户上尽可能测试你的想法,如果可能的话,你甚至应当和他们一起吃饭。 + +Guy Kawasaki [Rules] 强调过在倾听之外,*观察*你的用户的重要性。 + +我相信,合伙人和咨询师让客户说出他们内心真正想要的东西有巨大的困难。如果你想成为一个咨询师,建议你基于用户清晰的头脑以及他们的钱包来选择客户。 + +Next [如何得到晋升](03-How-to-Get-a-Promotion.md) diff --git a/zh/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md b/zh/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md new file mode 100644 index 0000000..5c73172 --- /dev/null +++ b/zh/3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md @@ -0,0 +1,13 @@ +# 如何获得晋升 +[//]: # (Version:1.0.0) +想要被提升为某种角色,先做那个角色该做的事情。 + +为了提升到某个位置,找到那个位置期望做的事情,然后去做。 + +想要得到薪酬的提升,带着信息去协商。 + +如果你觉得你值得得到提升,与你的 boss 聊一聊。清楚地问他们你需要做什么才能获得提升,然后努力去做。这听起来很老套,但大多数时候你对你需要做的事情的追求与你 boss 的想法是不同的。这可能会让你的 boss 在某些程度上有些失落。 + +大多数程序员可能在某些形式上对他们的相对能力有夸张的感觉 --- 毕竟,我们不可能都在前10%里!然而,我也见过一些非常不得志的人。人不能期望每个人的评价在什么时候都完美与现实相同,但我认为人们通常在一定程度上是公平的,有这样一个警告:如果别人看不到你的工作,你就得不到欣赏。有时候,因为偶然或个人习惯,有些人可能得不到太多关注。在家努力工作或者与你的团队和 boss 地理隔离的话,这会变得特别困难。 + +Next [服务你的团队 - 如何发展才能](../Serving-Your-Team/01-How-to-Develop-Talent.md) diff --git a/zh/3-Advanced/README.md b/zh/3-Advanced/README.md new file mode 100644 index 0000000..bc276e8 --- /dev/null +++ b/zh/3-Advanced/README.md @@ -0,0 +1,22 @@ +# 3. 高级 +[//]: # (Version:1.0.0) +- 技术评判 + - [如何从不可能中找到困难的部分](Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型语言](Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [选择语言](Technical-Judgment/03-Choosing-Languages.md) +- 机智地妥协 + - [如何与时间压力作斗争](Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用户](Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何获得晋升](Compromising-Wisely/03-How-to-Get-a-Promotion.md) +- 服务你的团队 + - [如何发展才能](Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何选择工作内容](Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何让你队友的价值最大化](Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何划分问题](Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何处理无聊的问题](Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何为工程获取支持](Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何发展一个系统](Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地沟通](Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告诉人们他们不想听的东西](Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何处理管理神话](Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何处理混乱的组织](Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/zh/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md b/zh/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md new file mode 100644 index 0000000..0812f3a --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md @@ -0,0 +1,23 @@ +# 如何发展才能 +[//]: # (Version:1.0.0) +Nietschze 夸大了他所说的: + +>那些无法摧毁我的,只会让我更强大 + +你最大的责任是对你的团队负责。你应该非常了解他们中的每个人。你应该激励你的团队,但不要让他们过劳。你通常应该告诉他们他们被激励的方式。如果他们觉得划算,他们会被很好的激励。每个工程中,或者在每个其他的工程里,试着同时用他们建议的以及你认为对他们好的方式去激励他们。激励他们的方法不是给他们更多工作,而是给他们一个新的技能或在团队里扮演一个新的角色。 + +你应该允许人们(包括你自己)偶尔失败,并且应该为一些失败预留一些时间。如果从未有失败,冒险也就没有意义。如果没有偶然的失败,说明其实你没有足够努力。当一个人失败了,你应该尽可能温柔地对待他,但不该把他们像成功了那样对待。 + +为了让每个团队成员被充分激励,问清楚他们中的每个人,如果他们没有动力的话,他们需要什么才能被充分激励。你可能需要让他们保持不满意的状态,但你需要知道每个人需要的是什么。 + +你不能放弃因为低落的情绪或者不满就故意不承担工作的那些人,然后就让他们这样懒散下去。你必须试着让他们充分被激励并且有效率。只要你有耐心,坚持这样做。当你的耐心耗尽时,就解雇他们吧。你不能允许故意不司其职的员工留在团队里,因为这对团队不公平。 + +通过在公众场合这样说,让你团队中的强大成员清楚地知道他们是强大的。表扬应当公开,批评应当私密。 + +团队中的强大成员会自然地比弱的成员有更多困难的任务。这是完美而自然的,没人会因此困扰,因为每个人都在努力工作。 + +一个在工资中没有反馈出来的奇怪的事实是,好的程序员比十个糟糕的程序员要有效率得多。这导致了一种奇怪的现象。通常,如果你们的弱程序员不挡道的话,你能跑的更快。如果你这样做了,事实上你在短期能取得更多进度。然而, 你的交易会失去一些重要的好处,叫做对弱小成员的训练,对集体知识的传递,失去强大程序员后的恢复能力。强大的程序员对这种现象应该温和些,并且从各种角度去考虑这个问题。 + +你可以经常给强大的团队成员有挑战的,但细致描绘的任务。 + +Next [如何选择工作的内容](02-How-to-Choose-What-to-Work-On.md) diff --git a/zh/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md b/zh/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md new file mode 100644 index 0000000..0fa3e6e --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md @@ -0,0 +1,5 @@ +# 如何选择工作的内容 +[//]: # (Version:1.0.0) +你需要在你个人的需要和团队的需要间权衡,选择需要做工程中的哪个部分。你应该做你最擅长的东西,但是也要试着去找一种方式来激励自己,不是通过承担更多的工作而是通过练习新的技能。领导才能和交流能力比技术能力更重要。如果你非常强大,承担最困难或最有风险的任务,在工程中尽可能早地完成这部分,以此减少风险。 + +Next [如何让你队友的价值最大化](03-How-to-Get-the-Most-From-Your-Teammates.md) diff --git a/zh/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md b/zh/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md new file mode 100644 index 0000000..848b62f --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md @@ -0,0 +1,15 @@ +# 如何让你队友的价值最大化 +[//]: # (Version:1.0.0) +为了让你的队友的价值最大化,发展好的团队精神,试着保持每个人的个人挑战与渴望。 + +为了发展团队精神,文化衫与聚会是有益的,但不如对个人的尊重。如果每个人尊重其他的每个人,就没有人会让其他人失望。团队精神产生于人们为团队做出牺牲,优先思考团队的利益而非自己利益的时候。作为一个领导者,在这个方面,没有付出就没有收获。 + +团队领导力的一个关键是促进团结,这样每个人都会听你的。有时候这意味着允许你的队友犯错。也就是,基于这种团结,如果对项目没有太大的损害,你必须允许你团队的一部分成员用他们自己的方式做事,即使你有很大的信心认为这是一件错事。当这种情况确实发生时,不要同意他们的观点,简单公开地反对之,然后接受这种团结。不要让人觉得你受伤了,或者认为你是被迫的,简单地陈述你不同意,但认为团队的团结是更加重要的。这经常会导致他们反悔。如果他们真的反悔了,不要坚持他们一开始的计划。 + +如果在你们从所有合适的角度讨论了这个话题后,有个人会反对,简单地告诉他们,你必须做一个决定,并且这就是你的决定。如果有方法去评估你的决定是否是错的,或者它稍后是否是错的,尽可能快速切换,并感激那个对的人。 + +询问你的团队,包括集体与个人这样一个问题:他们认为什么能创造团队精神以及创造一个高效的团队。 + +经常表扬,但不要浪费。尤其是表扬那些反对你且确实值得表扬的人。公开表扬,私下批评。但有这样一种例外:有时候进步或者纠正一个错误但却没有注意到错误的根源,是不能被表扬的,这种进步应该私下表扬。 + +Next [如何划分问题](04-How-to-Divide-Problems-Up.md) diff --git a/zh/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md b/zh/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md new file mode 100644 index 0000000..86f6ed4 --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md @@ -0,0 +1,9 @@ +# 如何划分问题 +[//]: # (Version:1.0.0) +接手一个软件工程并把它分为可以由个人实现的任务是很有趣的。这事应该及早进行。有时候经理可能会认为不考虑个人的项目能够起作用。这是不可能的,因为每个人的生产力是如此广泛地不同。对某个组件有特殊知识的人也经常改变,并且可以对工作效果有一个数量级的影响。 + +正如一个作曲家对其演奏乐器的音色的考虑,或者运动队教练对每个运动员的体能的考虑那样,有经验的团队领导,通常不能够把工程依据团队成员需要承担的角色那样划分成一个个的任务。这是好的团队不容易解散的一个原因。 + +因此有这样一种危险:人们在锻炼自己的能力时会感到无聊,并且不会提高他们的弱项或者学习新技能的能力。然而,如果不被过度使用的话,精通是一个非常有用的生产工具。 + +Next [如何处理无聊的任务](05-How-to-Handle-Boring-Tasks.md) diff --git a/zh/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md b/zh/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md new file mode 100644 index 0000000..bde52fd --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md @@ -0,0 +1,7 @@ +# 如何处理无聊的任务 +[//]: # (Version:1.0.0) +有时候避免对公司或工程的成功至关重要却很无聊的任务是不可能的。这些任务可能真的会降低那些必须执行它们的人的斗志。最好的处理方法是使用或者发扬 Larry Wall 的程序员懒惰美德。试着找一些方法让计算机去做这个任务,或者帮助你的队友去做这个。用一个程序花一个星期去完成要手动去用一个星期完成的任务能让你懂得更多,并且有时候这是可重用的。 + +如果所有其他的途径都不能工作,为那些必须做这个无聊任务的人道歉,但无论什么情况,不要让他们去单独完成它。至少安排一个两人团队去做这个事情,并增强健康的团队协作来完成这个任务。 + +Next [如何为工程获取支持](06-How-to-Gather-Support-for-a-Project.md) diff --git a/zh/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md b/zh/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md new file mode 100644 index 0000000..adc8cac --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md @@ -0,0 +1,5 @@ +# 如何为工程获取支持 +[//]: # (Version:1.0.0) +要给工程获取支持,需要创建并交流一个能够证明这个组织整体的真正价值的愿景。试着让其他人分享他们对你所创造的愿景的观点。这给他们一个理由去支持你并给予你他们的观点所带来的价值。独立地为你的工程补充关键的支持者。不论在什么可能的地方,展示,但不告诉。如果可能的话,构建一个原型或者一个模型来证明你的主意。一个原型总是有力的,但在软件中,它比任何书面的描述都要高级得多。 + +Next [如何发展一个系统](07-How-to-Grow-a-System.md) diff --git a/zh/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md b/zh/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md new file mode 100644 index 0000000..c6e06b1 --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md @@ -0,0 +1,23 @@ +# 如何发展一个系统 +[//]: # (Version:1.0.0) +树的种子包含了成长的思想,但不完全实现成长体的形式与力量。胚胎会成长。它会变大。它看起来更像成长体,并越来越有用。最终它孕育果实。最后,它死亡并且它的躯体喂养了其他的有机体。 + +对待软件我们也应当有这样的荣耀。一架桥不是这样的,永远不会有一架婴儿桥,但只是有一座未完成的桥。桥比软件要简单得多。 + +认识到软件的成长是有益的,因为这允许我们在有一个完美的思维图景前取得有用的进步。我们可以从用户那里获得反馈,并用之纠正这种成长。修剪掉疲软的四肢才能健康。 + +程序员必须设计一个完成的可分发可使用的系统。但高级程序员需要做的更多。你必须设计一个终止于完结系统的成长路线。你的工作是,得到一个想法的萌芽,然后把它尽可能顺利地变成一个有用的人工制品。 + +因此,你必须模拟最终的结果,用一种工程团队可以为之雀跃的方式去交流。但你也必须和他们交流一条非跳跃式的路径,从他们所知到他们想要成为的地方去。在整个过程中,这棵树必须活着,它不能在什么时候死去,然后又复活过来。 + +这条路径会是螺旋发展的。里程碑之间永远不会太远,这对于在路上取得进步是有用的。在极端的商业环境里,如果里程碑可以实现并尽早赚钱是最好的。即使他们离良好设计的端点还有很远。程序员的一个工作就是通过理智的选择用里程碑表示的成长路径来平衡即时的报酬与将来的报酬。 + +高级程序员对软件,团队,个人的成长有集体责任。 + +一个读者,Rob Hafernik,在这一节中写下了这样的评论: + +> 我认为你过低强调了这里的重要性。不仅是系统,还有算法,用户界面,数据模型,等等。因为你工作在一个庞大的系统中,必须有即时目标相关的可测量的进步,所以这些也是*至关重要的*。没有什么比抵达终点却发现一切都不能工作更加恐怖(看看最近的投票新闻系统的崩溃吧)。我甚至想进一步把这当做自然的法则:没有庞大,复杂的系统可以由碎片实现,这只能由一个简单的系统循序渐进成长为一个复杂的系统。 + +对此,我们只能回答,*要有光*! + +Next [如何有效地沟通](08-How-to-Communicate-Well.md) diff --git a/zh/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md b/zh/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md new file mode 100644 index 0000000..08d6c6c --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md @@ -0,0 +1,11 @@ +# 如何有效地沟通 +[//]: # (Version:1.0.0) +为了良好地沟通,你必须认识到它的困难。它本身就是一种技能。与你交流的人本身是有瑕疵的,这一事实使得沟通变得更加困难。他们不会努力去理解你。他们不善言辞。他们经常过度工作或者无聊,至少,有时候只关注他们自己的工作而非你要发表的长篇大论。上课,练习写作,公共演讲,聆听,这些东西的一个好处是,如果你擅长它们,你可以更容易看到问题所在以及解决方法。 + +程序员是一种依赖于与团队交流而生存的社会动物。高级程序员是一种依赖于与团队外的人交流而满意的社会动物。 + +程序员从混沌中带来秩序,一种实现这一目标的有趣方法是从外部的一个提议开始。这能用*稻草人*或*白纸*模式或者口头的方式来完成。这种领导对于让团队置身于辩论中有极大的好处。这也把你暴露到批评,或者拒绝与否定中。高级程序员必须准备好接受这些,因为他有特殊的能力,也因此有特殊的责任。非程序员出身的企业家需要程序员在某些方面提供领导。程序员是思想与现实之间的一部分桥梁。 + +我没有很好地掌握沟通的技巧,但我正在尝试的是一种四叉路径:在我有了一些有序的主意并且充分准备好后,我试着口头表达,交给人们一张白纸(可能是真实的纸,也可能是电子的)来给他们展示一个 demo,然后耐心地重复这个过程。很多次我想过,我们在这种困难的沟通里还是不够耐心。如果你的想法没有马上被接受,你不应该丧气。如果你在准备中投入了精力,没有人会因此看低你。 + +Next [如何告诉人们他们不想听的东西](09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) diff --git a/zh/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md b/zh/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md new file mode 100644 index 0000000..fa4f1b7 --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md @@ -0,0 +1,9 @@ +# 如何告诉人们他们不想听的东西 +[//]: # (Version:1.0.0) +你会经常需要告诉人们一些让他们不舒服的事情。记住,你必须为某种原因才这样做。即使没有什么可以用来解决这个问题,你也该尽早告诉他们,这样他们才能充分警觉。 + +向别人指出一个问题的最好方法是同时提供一个解决方案。其次的方法是呼吁他们寻求帮助。如果你有不被信任的危险,你应该为你的主张寻求支持。 + +一种你必须说的最不舒服且普遍的事情是“时间不够”。尽责的程序员讨厌这样说,但必须尽早说。没有什么比 deadline 抵达,不得不推迟进度更加糟糕,即使唯一的行动是通知每个人。更好的做法是,作为一个团队整体来做这件事,如果物理上做不到,至少是精神上这样做。你会想要得到你的团队对你的观点以及你为之所做的事情的支持,团队必须与你共同面对这样的后果。 + +Next [如何处理管理神话](10-How-to-Deal-with-Managerial-Myths.md) diff --git a/zh/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md b/zh/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md new file mode 100644 index 0000000..3d18a0e --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md @@ -0,0 +1,12 @@ +# 如何处理管理神话 +[//]: # (Version:1.0.0) +*神话*这个词有时候意味着虚构。但这有着更深层的内涵。它也意味着一些解释宇宙以及和人类和宇宙之间的关系的宗教故事。管理者倾向于忘记他们作为一个程序员时学到的东西,并且相信某种传说。试着让他们相信这种传说是错的,正如让一个虔诚的宗教信徒从他们的信仰中醒悟过来一样粗鲁而失败。因此,你应该认可这些信仰: + +- 文档越多越好。(他们需要文档,但他们不会想要你在这些东西上花时间。) +- 程序员是平等的。(程序员可以按重要程度分类。) +- 分配更多资源给迟来的项目可以让它加速。(与新人的交流的代价大多数时候很繁重并且无用。) +- 程序员的效率可以用一些简单的标准尺度来度量,比如代码行数(如果简洁才是力量,那么代码行数是坏的,而非好的。) + +如果有机会,你可以试着解释这些东西,但如果你没有成功,不要觉得悲伤,不要好斗地反对这些神话以致损害了你的声望。每个这样的神话增强了管理者关于他们有一些对正在进行的事情的实际控制的想法。真相是,如果管理者是好的,他们会帮助你,如果他们是坏的,他们会妨碍你。 + +Next [如何处理组织混乱](11-How-to-Deal-with-Organizational-Chaos.md) diff --git a/zh/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md b/zh/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md new file mode 100644 index 0000000..b7236df --- /dev/null +++ b/zh/3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md @@ -0,0 +1,11 @@ +# 如何处理组织混乱 +[//]: # (Version:1.0.0) +经常会有短暂的组织混乱,比如解雇,收购,IPO,新雇佣,等等。对每个人来说这都是令人不安的,但可能对于那些将自尊建立在能力而非位置上的程序员来讲,这种不安不会那么严重。组织混乱对程序员来讲是锻炼他们的魔力的好机会。因为这是一个集体秘密,在最后我会有所保留。如果你不是一个程序员,就不要再读下去了。 + +> 工程师有能力去创造与维持。 + +非工程师可以安排人们,但,在典型的软件公司,如果没有程序员的话,他们不能创造与维持任何东西,正如工程师通常不能有效地销售产品或者管理商业。这种力量对于大多数与临时组织混乱相关的问题是一种抵抗。如果你有这种力量,你应当完全忽视这种混乱并当做什么都没发生那样坚持下去。你可能,当然,被解雇,但如果这发生了,你可能因为这种力量得到新的工作。更普遍的,一些紧张的没有这种魔力的人会进入你的空间并告诉你做一些蠢事。如果你真的确信这是一件蠢事,最好的做法是微笑,点头,直到他们走开,然后继续做你认为对公司最好的事情。 + +如果你是一个领导者,告诉你的员工做一样的事情,告诉他们忽视其他任何人告诉他们的东西。这种行为的过程对你个人是最好的,对你的公司或工程也是最好的。 + +Next [词汇表](../../4-Glossary.md) diff --git a/zh/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md b/zh/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md new file mode 100644 index 0000000..494edab --- /dev/null +++ b/zh/3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md @@ -0,0 +1,9 @@ +# 如何从不可能中找到困难的部分 +[//]: # (Version:1.0.0) +解决困难,识别不可能是我们的工作。大多数职业程序员认为,如果有些问题不能从一个简单系统发展而来,或者不能评估,那它就是不可能实现的。然而,根据这个定义,研究本身就是不可能的。大量的工作是困难的,但不是必然不可能的。 + +这种区别是滑稽的,因为你可能经常被要求做一些事实上不可能的事情,不论是从科学观点还是从软件工程观点。然后你的工作就变成了帮助老板找到一个合理的,仅仅是困难而非不可能的解决方案,去满足他们大部分的需要。当一个解决方案可以被自信地规划且风险可以预料时,它只是困难而已。 + +砍掉模糊的需求是不可能的,比如“构建一个系统为任何人计算最受欢迎的发型和颜色”。如果需求可以做得更加细致,它就经常会变成仅仅是困难,比如“构建一个系统去计算某个人的发型和颜色,允许他们预览与做出改变,让顾客在原始风格的基础上满意度变大,这样我们就可以赚很多钱”。如果没有关于成功的清晰定义,你就不会成功。 + +Next [如何使用嵌入型语言](02-How-to-Utilize-Embedded-Languages.md) diff --git a/zh/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md b/zh/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md new file mode 100644 index 0000000..8f7f7b8 --- /dev/null +++ b/zh/3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md @@ -0,0 +1,11 @@ +# 如何使用嵌入型语言 +[//]: # (Version:1.0.0) +把一种编程语言嵌入到一个系统对程序员来讲有着几乎与性一样的魔力。这是一种最具有创造力的可以表现的行为。这使得系统惊人地强大。这也允许你锻炼大多数创造性和有生命力的能力,把系统变成你的朋友。 + +世界上最好的文本编辑器都有嵌入性语言。这可以被用于预计的观众可以掌握的语言的范围,语言的使用可以变为可选的,正如文本编辑器里那样,这样在一开始可以使用它,而没有其他人必须使用它。 + +我和许多其他的程序员曾坠入创造特殊目的的嵌入型语言的困境里。我曾经历过两次。已经存在了许多为嵌入型语言设计的语言,在创造一个新的语言前,你应该三思。 + +使用嵌入型语言前,真实的需要自问的问题是:这种工作与我的观众的文化是一致还是相悖?如果你的目标观众都是非程序员,这会有帮助吗?如果你的目标观众都是非程序员,他们会更喜欢 API 吗?他会是什么语言?程序员不会想要学习一种新的使用范围很窄的语言,但如果这与他们的文化混在一起了,他们将不会花太多时间去学习它。创造一种新的语言是一种快乐。但我们不应该让这遮蔽了观察用户的双眼。除非你有一些真正原始的需求与想法,为什么不使用一种已存在的语言呢?这样你就可以利用好用户对它已有的这种熟悉了。 + +Next [选择语言](03-Choosing-Languages.md) diff --git a/zh/3-Advanced/Technical-Judgment/03-Choosing-Languages.md b/zh/3-Advanced/Technical-Judgment/03-Choosing-Languages.md new file mode 100644 index 0000000..09cc157 --- /dev/null +++ b/zh/3-Advanced/Technical-Judgment/03-Choosing-Languages.md @@ -0,0 +1,15 @@ +# 选择语言 +[//]: # (Version:1.0.0) +喜欢程序员这份工作的独立的程序员可以为任务选择最好的语言。大多数职业程序员控制不了他们将要使用的语言。通常,这个话题会由执行行政决议而非技术决议的 boss 说出,他们缺少勇气去提升新型工具,即使他们知道,大多数时候使用最新的知识,最少被接受的工具是最好的。另一些情况下,这种团体中真实的好处,以及拓展一个更大的社区的好处,排除了个人的选择。通常管理者由能够雇用在给定的语言有些经验的程序员的需求所驱动。毫无疑问他们服务于他们所追求的,以成为工程或公司的最佳乐趣,而且他们会以此被尊敬。并且,我个人相信,这种最浪费而且错误的常见行为,你很有可能遇到。 + +但是,当然,事物永远不会是一维的。即使一种核心语言妥协了,超出了你的控制范围,通常的情况是,工具和其他程序可以且应该由另一种不同的语言来编写。如果一种语言需要作为嵌入型的(你通常都要考虑它!),语言的选择很大程度上会依赖于使用者的文化。一个人应该利用好这个问题来为你的公司或工程服务,为任务使用最好的语言,这样可以让工作变得有趣。 + +一门编程语言,如果学习它比学习自然语言还要难,那它真的应该被称为符号。对初学者和一些门外汉来说“学习一门新语言”像是一个令人生畏的任务,但在你掌握了三种语言后,这只是一个熟悉可用的库的简单问题。一个程序员趋向于思考一个由三四门语言组成的一个大杂烩系统,但我认为这样一个系统在以下几方面要比单一语言系统在很多情况下要强大: + +- 不同符号编写的部分间,必要的松耦合存在(虽然可能没有干净的接口) +- 通过独立重写每个组件,你可以轻松地写出一个新的语言平台 +- 只有一门语言可能对一个庞大的系统不太适合 - 你的多个模块由多种语言组成,能让你为任务找到正确的工具。 + +这些效应可能有些只是心理上的,但心理上的东西也很重要。最后要说的是,语言暴政的代价超过了它能提供的所有好处。 + +Next [明智地妥协 - 如何与时间压力斗争](../Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) diff --git a/zh/4-Glossary.md b/zh/4-Glossary.md new file mode 100644 index 0000000..de32ba9 --- /dev/null +++ b/zh/4-Glossary.md @@ -0,0 +1,110 @@ +# 词汇表 +[//]: # (Version:1.0.0) +这是这篇文章里用到的一些短语的词汇表。它们不一定是人们熟悉的标准含义,Eric S. Raymond 曾经编译过一份信息量巨大的词汇表 [HackerDict],如果你能理解其中的一些片段,阅读这个词汇表将是惊喜而愉悦的。 + +**unk-unk** +: unknown-unknown 的简写。指的是一些暂时不能被概念化的问题,它们会偷走项目的时间并且阻塞时间表。 + +**boss** +: 给你任务的人或实体,有些地方可能泛指公众。 + +**printlining** +: 在严格的临时机制上,在程序中插入一些语句,为调试输出一些程序执行过程中的信息。 + +**logging** +: 实践中编写程序的一种方式,使得它能够产生可设置的输出以描述它的执行过程。 + +**分治** +: 一种自上而下设计的技术,更重要的是,一种调试的技术,划分问题或谜题为小的问题或谜题。 + +**vapour** +: 幻觉,而且通常是对还不能出售的软件虚假的承诺,往往不会物质化为任何固定的东西。 + +**boss** +: 给你设定任务的人,有些时候,也指用户。 + +**tribe** +: 与你一同为相同目标奋斗的人们。 + +**低垂的水果** +: 轻易能达到的巨大提升。 + +**主办人** +:项目的发起人 + +**垃圾** +: 不再需要被放在内存中的对象 + +**商业** +: 一群为财富聚合在一起的人 + +**公司** +: 一群为财富聚合在一起的人 + +**集体** +: 一群与你共享文化亲缘与忠诚的人。 + +**滚动目盲** +: 一种由于有效信息被太多无效信息掩盖导致你不能发现它的效应 + +**挂钟** +: 由挂钟测量的现实中真实的时间,与 CPU 时间相对。 + +**瓶颈** +: 系统性能最重要的限制/一个可以限制性能的界限。 + +**主线** +: 一个独特的信息块,所有缓存副本都从它继承而来,作为这份数据的官方版本。 + +**分配的堆** +: 一份内存在这样的情况下可以被称为分配了堆:当释放它的机制已经完成时。 + +**垃圾** +: 已经被分配但不再有有效意义的内存。 + +**GC** +: 一个回收垃圾的系统。 + +**内存泄露** +: 无意持有的一系列对象的引用,它们避免了垃圾回收(或者垃圾回收器或内存管理系统中的 bug!)导致程序随时间逐渐增加了它的内存占用。 + +**极限编程** +: 一种强调与客户交流以及自动化测试的编程风格。 + +**碰壁** +: 因为耗尽了某种特定的资源导致性能突然大幅度地降级 + +**投机编程** +: 在知道一个东西有用前就把它做出来。 + +**信息隐藏(封装)** +: 通过使用尽可能少暴露信息的接口来让事情保持独立解耦的一种设计原则。 + +**面向对象编程** +: 一种强调在对象内部管理状态的编程风格。 + +**交流语言** +: 一种优先为标准化而非执行设计的语言。 + +**箱子与箭头** +: 一种宽松,非正式的,由箱子和箭头组合而成表达关系的图表制作风格,这与正式的图表方法论,比如 UML,相对。 + +**通用语** +: 一种语言是如此受欢迎以至于它成了它的领域中实际上的标准,例如法语一度成为国际外交的手段。 + +**buy vs. build** +: 用来形容购买软件还是自己编写软件这样的选择。 + +**合并工作** +: 需要很少创造力并产生很少风险的工作,合并工作可以被很容易地评估。 + +**编程符号** +: 编程语言的同义词,强调编程语言的数学本质以及它们与自然语言相比的简单之处。 + +**稻草人** +: 一种用来作为技术讨论起点的文档。稻草人也可以引申出火柴人,罐头人,木头人,铁人,等等。 + +**白纸** +: 一种信息文档,通常用来解释或将产品或思想卖给观众而非程序员。 + +Next [书籍/网站](5-Bibliography.md) diff --git a/zh/5-Bibliography.md b/zh/5-Bibliography.md new file mode 100644 index 0000000..a3e97a6 --- /dev/null +++ b/zh/5-Bibliography.md @@ -0,0 +1,31 @@ +# 附录 A - 书目/网站目录 +[//]: # (Version:1.0.0) +## 书目 + +[Rules00] Guy Kawasaki, Michelle Moreno, and Gary Kawasaki. 2000. HarperBusiness. Rules for Revolutionaries: The Capitalist Manifesto for Creating and Marketing New Products and Services. + +[RDev96] Steve McConnell. 1996. Microsoft Press. Redmond, Wash. Rapid Development: Taming Wild Software Schedules. + +[CodeC93] Steve McConnell. 1993. Microsoft Press. Redmond, Wash. Code Complete. + +[XP99] Kent Beck. 1999. 0201616416. Addison-Wesley. Extreme Programming Explained: Embrace Change. + +[PlanXP00] Kent Beck and Martin Fowler. 2000. 0201710919. Addison-Wesley. Planning Extreme Programming. + +[Prag99] Andrew Hunt, David Thomas, and Ward Cunningham. 1999. 020161622X. Addison-Wesley. The Pragmatic Programmer: From Journeyman to Master. + +[Stronger] Friedrich Nietzsche. 1889. Twilight of the Idols, "Maxims and Arrows", section 8.. + +## 网站 + +[PGSite] Paul Graham. 2002. Articles on his website: [http://www.paulgraham.com/articles.html](http://www.paulgraham.com/articles.html). All of them, but especially "Beating the Averages". + +[Hacker] Eric S. Raymond. 2003. How to Become a Hacker. [http://www.catb.org/~esr/faqs/hacker-howto.html](http://www.catb.org/~esr/faqs/hacker-howto.html). + +[HackDict] Eric S. Raymond. 2003. The New Hacker Dictionary. [http://catb.org/esr/jargon/jargon.html](http://catb.org/esr/jargon/jargon.html). + +[ExpCS] Edsger W. Dijkstra. 1986. How Experimental is Computing Science?. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD988a.PDF). + +[Knife] Edsger W. Dijkstra. 1984. On a Cultural Gap. [http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF](http://www.cs.utexas.edu/users/EWD/ewd09xx/EWD913.PDF). + +Next [History](6-History.md) diff --git a/zh/6-History.md b/zh/6-History.md new file mode 100644 index 0000000..e6edd54 --- /dev/null +++ b/zh/6-History.md @@ -0,0 +1,47 @@ +# 附录 B - 历史 +[//]: # (Version:1.0.0) +## 迁移到 Github + +这篇文章已经在 github 上作为一个仓库创建了,这样它可以很容易地被分享、更新、提高。它是从这里复制过来的。[http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm](http://samizdat.mines.edu/howto/HowToBeAProgrammer.htm) by [Braydie Grove](https://github.com/braydie)。 2016年1月迁移到 github。 + +## 希望反馈或扩展。 + +请将你对这篇文章的任何评论发给我,我会考虑所有的建议,大部分都会对这篇文章有所帮助。 + +这篇文章处于 GNU 免费文档授权下。这个授权不是专门为文章而设计的。文章通常有连贯的令人信服的服务于一个中心的论据。我希望这篇文章尽量短而易读。 + +我希望它是说明性的,尽管不是一本教科书,它被划分成许多小节,这样新的章节可以被自由地添加进去。有了这样的倾向,你可以用你觉得合适的方式来扩展这篇文章,且服从这个授权的规定。 + +可能认为这个文档值得扩展有点自大,但希望生生不息。我会很高兴看到你用以下的方式扩展它: + +对每个章节增加一些阅读理解, + +增加更多章节, + +翻译为其他语言,即使只是一小部分一小部分地翻译,或者 + +在文字间留下批评或评论, + +用不同形式构建的能力:比如 palm 格式或更好的 HTML 格式。 + +如果你向我传达了你的工作,我会考虑把它包括在我的子版本里,遵循这个许可证的规定。你也可以在我的了解之外制作你自己的版本,正如这个协议所说的。 + +Thank you. + +Robert L. Read + +## 原始版本 + +这个文档的原始版本由 Robert L. Read 在2000年制作,并且以电子形式在2002年首发于 Samizdat Press(http://Samizdat.mines.edu) 。被 Hire.com 的程序员所使用。 + +在这篇文章2003年被 Slashdot 刊载后,大概有75个人给我发过邮件提过建议与错误修改。我感激他们中的所有人。可能有很多重复,但这些人不是提出来最主要的建议就是第一个找到了我的 bug:Morgan McGuire, David Mason, Tom Moertel, Ninja Programmer (145252) at Slashdot, Ben Vierck, Rob Hafernik, Mark Howe, Pieter Pareit, Brian Grayson, Zed A. Shaw, Steve Benz, Maksim Ioffe, Andrew Wu, David Jeschke, 以及 Tom Corcoran。 + +最后,我想感谢 Christina Vallery,他的编辑和校对巨大地提高了第二份草稿,还有 Wayne Allen,他鼓励我开始了这件事情。 + +## 原始作者的简介 + +Robert L. Read 生活在德克萨斯,奥斯汀, 有一个妻子和两个孩子,他现在是 Hire.com 的首席工程师。他在那里工作了四年。在这之前他建立了 4R 科技,为造纸工业生产基于扫描的图像分析质量控制工具。 + +Rob 在1995年在德州大学获得数据库理论方向的计算机博士学位。1987年他在 Rice 大学获得计算机科学学士学位,在16岁时,他就是一个带薪程序员了。 + +Next [License](LICENSE.md) diff --git a/zh/7-Contributions.md b/zh/7-Contributions.md new file mode 100644 index 0000000..1068ae8 --- /dev/null +++ b/zh/7-Contributions.md @@ -0,0 +1,34 @@ +# Contributions +[//]: # (Version:1.0.0) +这个仓库目标是成为一个社区驱动的工程,你的加入会极大地促进这个向导的质量。 + +## 我可以做什么贡献? + +有很多方式为 "How to be a Programmer" 做贡献 + +- 新章节的思想 +- 提升已有的章节 +- 识别排版错误或其他章节中的问题 +- 为章节提供额外的资源链接 +- 一般的用于提升工程的建议 +- 为这份指导提供翻译 + +## 翻译 + +当前,这份指导已经从英文翻译为以下语言: + +- 中文 by [ahangchen](https://github.com/ahangchen) +- Spanish by [Maximiliano Murua](https://gitlab.com/maximiliano.murua) + + **如果你第一个提供了其他语言的翻译,你就是这个工程的一个明确的贡献者,请帮忙维护和 review 对翻译版本的修改。** + + +## 贡献者 + +Github 在这里会维护一个所有贡献者的列表 [contributors](https://github.com/braydie/HowToBeAProgrammer/graphs/contributors) + +## 校正与迁移到GitHub + +[Braydie Grove](https://www.github.com/braydie) 已经同意作为主编。 + +Braydie 把原始的文档转成了 Markdown 的形式并创建了这个仓库。 diff --git a/zh/LICENSE.md b/zh/LICENSE.md new file mode 100644 index 0000000..e579b65 --- /dev/null +++ b/zh/LICENSE.md @@ -0,0 +1,12 @@ + +## Creative Commons Attribution Share-Alike +[//]: # (Version:1.0.0) +"How To Be A Programmer: Community Version" by Robert L. Read with Community is licensed under Creative Commons Attribution Share-Alike Internal v 4.0. + +At present this work will be edited by Braydie Grove and Robert L. Read. + +We will make reasonable attempts to maintain proper attributions of contributions in the section entittle "Contributions". If you make a pull-request with a significant contribution, please add a very brief description of your contribution to that section. + + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/zh/README.md b/zh/README.md new file mode 100644 index 0000000..70e34cb --- /dev/null +++ b/zh/README.md @@ -0,0 +1,112 @@ +# How to be a Programmer 中文版 +Robert L. Read with Community +[//]: # (Version:1.0.0) +Copyright 2002, 2003, 2016 Robert L. Read + +Licensed under [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). + +翻译:[梦里风林](https://github.com/ahangchen) + +原文:[HowToBeAProgrammer](https://github.com/braydie/HowToBeAProgrammer) + +如果您希望改进这份中文翻译,请向这个[分支](https://github.com/ahangchen/HowToBeAProgrammer)提交Pull request。 + +[可以在gitbook在线阅读或导出PDF。](https://braydie.gitbooks.io/how-to-be-a-programmer/content/zh/index.html) + +文章中出现的一些词汇往往有特殊的含义,可以在[4-词汇表](4-Glossary.md)找到注释。 + +## 引言 +  做一个好的程序员,困难而高尚。将一个软件工程集体愿景变为现实,最困难的地方在于与你的同事和顾客相处。编程很重要,这需要强大的智力和技能。 但在好的程序员看来,相比构建一个让客户和各种各样的同事都满意的软件系统,(纯粹的)编程真的只是小孩子的玩意。在这篇文章里,我尝试尽可能简洁地总结那些当我21岁时,希望别人告诉我的事。 + +  这可能很主观的,所以,这篇文章注定不适用于所有人,并且有的内容有点武断。我尽量写一些程序员在ta的工作中,非常可能会遇到的事情。大部分这些问题以及它们的解决方案在人们的环境中如此普遍,以至于我(说的)可能有点唠叨。尽管如此,我还是希望这篇文章是有用的。 + +  我们在课堂上学习编程。 那些著作: The Pragmatic Programmer [Prag99], Code Complete [CodeC93], Rapid Development [RDev96], 以及 Extreme Programming Explained [XP99] 都传授编程(知识),并阐述做一个好的程序员这个大话题。 在读这篇文章之前,或者就是现在,你当然也应该读一读Paul Graham [PGSite] 和 Eric Raymond [Hacker] 的文章。 但与那些著作不同,这篇文章强调社交问题并且总结了整套我所知的必须的技能。 + +  在这篇文章里,boss这个词指的是任何一个交给你工程去做的人。 除了一些语境外,我会同义地使用交易,公司,集体这些词,比如,交易意味着赚钱,公司意味着现代的工作空间,集体一般是那些你一起工作的人。 + +  欢迎来到这个群体。 + +## 目录 + +1. [入门](1-Beginner) + - 个人技能 + - [学会 Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [如何通过分割问题 Debug](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一个错误](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日志调试](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能问题](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解决性能问题](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何优化循环](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何处理 I/O 开销](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理内存](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [如何处理偶现的 Bug](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何学习设计技能](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何进行实验](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - 团队技能 + - [为什么预估很重要](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [如何预估编程时间](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人们作为信息源](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何优雅地写文档](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代码上工作](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代码控制](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何进行单元测试](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [毫无头绪?休息一下](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何决定下班时间](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何与不好相处的人相处](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [进阶](2-Intermediate) + - 个人技能 + - [如何保持活力](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被广泛信任](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在时间和空间之间该如何权衡](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何进行压力测试](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [如何权衡简洁与抽象](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何学习新技能](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [学会打字](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [如何进行集成测试](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流语言](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [重型工具](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [如何分析数据](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - 团队技能 + - [如何管理开发时间](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方软件风险](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理咨询](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [如何适度交流](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言异议以及如何避免](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - 评判 + - [如何权衡开发质量与开发时间](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理软件系统依赖](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何评判软件是否太不成熟了](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何决定购买还是构建](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何专业地成长](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [如何评估面试者](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何决定什么时候使用奇妙的计算机科学](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何与非工程师交谈](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [高级](3-Advanced) + - 技术评判 + - [如何从不可能中找到困难的部分](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型语言](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [选择语言](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - 机智地妥协 + - [如何与时间压力作斗争](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用户](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何获得晋升](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - 服务你的团队 + - [如何发展才能](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何选择工作内容](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何让你队友的价值最大化](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何划分问题](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何处理无聊的问题](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何为工程获取支持](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何发展一个系统](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地沟通](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告诉人们他们不想听的东西](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何处理管理神话](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何处理混乱的组织](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [词汇表](4-Glossary.md) +5. [附录 A - 书籍/网站](5-Bibliography.md) +6. [附录 B - 历史 (至2016年1月)](6-History.md) +6. [附录 C - 贡献 (至2016年1月)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. diff --git a/zh/SUMMARY.md b/zh/SUMMARY.md new file mode 100644 index 0000000..434e002 --- /dev/null +++ b/zh/SUMMARY.md @@ -0,0 +1,89 @@ +# How to be a Programmer 中文版 +[//]: # (Version:1.0.0) +原文出自 https://github.com/braydie/HowToBeAProgrammer +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. + +## 目录 + +1. [入门](1-Beginner/README.md) + - 个人技能 + - [学会 Debug](1-Beginner/Personal-Skills/01-Learn-To-Debug.md) + - [如何通过分割问题 Debug](1-Beginner/Personal-Skills/02-How-to-Debug-by-Splitting-the-Problem-Space.md) + - [如何移除一个错误](1-Beginner/Personal-Skills/03-How-to-Remove-an-Error.md) + - [如何使用日志调试](1-Beginner/Personal-Skills/04-How-to-Debug-Using-a-Log.md) + - [如何理解性能问题](1-Beginner/Personal-Skills/05-How-to-Understand-Performance-Problems.md) + - [如何解决性能问题](1-Beginner/Personal-Skills/06-How-to-Fix-Performance-Problems.md) + - [如何优化循环](1-Beginner/Personal-Skills/07-How-to-Optimize-Loops.md) + - [如何处理 I/O 开销](1-Beginner/Personal-Skills/08-How-to-Deal-with-IO-Expense.md) + - [如何管理内存](1-Beginner/Personal-Skills/09-How-to-Manage-Memory.md) + - [如何处理偶现的 Bug](1-Beginner/Personal-Skills/10-How-to-Deal-with-Intermittent-Bugs.md) + - [如何学习设计技能](1-Beginner/Personal-Skills/11-How-to-Learn-Design-Skills.md) + - [如何进行实验](1-Beginner/Personal-Skills/12-How-to-Conduct-Experiments.md) + - 团队技能 + - [为什么预估很重要](1-Beginner/Team-Skills/01-Why-Estimation-is-Important.md) + - [如何预估编程时间](1-Beginner/Team-Skills/02-How-to-Estimate-Programming-Time.md) + - [如何搜索信息](1-Beginner/Team-Skills/03-How-to-Find-Out-Information.md) + - [如何把人们作为信息源](1-Beginner/Team-Skills/04-How-to-Utilize-People-as-Information-Sources.md) + - [如何优雅地写文档](1-Beginner/Team-Skills/05-How-to-Document-Wisely.md) + - [如何在垃圾代码上工作](1-Beginner/Team-Skills/06-How-to-Work-with-Poor-Code.md) + - [如何使用源代码控制](1-Beginner/Team-Skills/07-How-to-Use-Source-Code-Control.md) + - [如何进行单元测试](1-Beginner/Team-Skills/08-How-to-Unit-Test.md) + - [毫无头绪?休息一下](1-Beginner/Team-Skills/09-Take-Breaks-when-Stumped.md) + - [如何决定下班时间](1-Beginner/Team-Skills/10-How-to-Recognize-When-to-Go-Home.md) + - [如何与不好相处的人相处](1-Beginner/Team-Skills/11-How-to-Deal-with-Difficult-People.md) +2. [进阶](2-Intermediate/README.md) + - 个人技能 + - [如何保持活力](2-Intermediate/Personal-Skills/01-How-to-Stay-Motivated.md) + - [如何才能被广泛信任](2-Intermediate/Personal-Skills/02-How-to-be-Widely-Trusted.md) + - [在时间和空间之间该如何权衡](2-Intermediate/Personal-Skills/03-How-to-Tradeoff-Time-vs-Space.md) + - [如何进行压力测试](2-Intermediate/Personal-Skills/04-How-to-Stress-Test.md) + - [如何权衡简洁与抽象](2-Intermediate/Personal-Skills/05-How-to-Balance-Brevity-and-Abstraction.md) + - [如何学习新技能](2-Intermediate/Personal-Skills/06-How-to-Learn-New-Skills.md) + - [学会打字](2-Intermediate/Personal-Skills/07-Learn-to-Type.md) + - [如何进行集成测试](2-Intermediate/Personal-Skills/08-How-to-Do-Integration-Testing.md) + - [交流语言](2-Intermediate/Personal-Skills/09-Communication-Languages.md) + - [重型工具](2-Intermediate/Personal-Skills/10-Heavy-Tools.md) + - [如何分析数据](2-Intermediate/Personal-Skills/11-How-to-analyze-data.md) + - 团队技能 + - [如何管理开发时间](2-Intermediate/Team-Skills/01-How-to-Manage-Development-Time.md) + - [如何管理第三方软件风险](2-Intermediate/Team-Skills/02-How-to-Manage-Third-Party-Software-Risks.md) + - [如何管理咨询](2-Intermediate/Team-Skills/03-How-to-Manage-Consultants.md) + - [如何适度交流](2-Intermediate/Team-Skills/04-How-to-Communicate-the-Right-Amount.md) + - [如何直言异议以及如何避免](2-Intermediate/Team-Skills/05-How-to-Disagree-Honestly-and-Get-Away-with-It.md) + - 评判 + - [如何权衡开发质量与开发时间](2-Intermediate/Judgment/01-How-to-Tradeoff-Quality-Against-Development-Time.md) + - [如何管理软件系统依赖](2-Intermediate/Judgment/02-How-to-Manage-Software-System-Dependence.md) + - [如何评判一个软件是否太不成熟了](2-Intermediate/Judgment/03-How-to-Decide-if-Software-is-Too-Immature.md) + - [如何决定购买还是构建](2-Intermediate/Judgment/04-How-to-Make-a-Buy-vs-Build-Decision.md) + - [如何专业地成长](2-Intermediate/Judgment/05-How-to-Grow-Professionally.md) + - [如何评估面试者](2-Intermediate/Judgment/06-How-to-Evaluate-Interviewees.md) + - [如何决定什么时候使用奇妙的计算机科学](2-Intermediate/Judgment/07-How-to-Know-When-to-Apply-Fancy-Computer-Science.md) + - [如何与非工程师交谈](2-Intermediate/Judgment/08-How-to-Talk-to-Non-Engineers.md) +3. [高级](3-Advanced/README.md) + - 技术评判 + - [如何从不可能中找到困难的部分](3-Advanced/Technical-Judgment/01-How-to-Tell-the-Hard-From-the-Impossible.md) + - [如何使用嵌入型语言](3-Advanced/Technical-Judgment/02-How-to-Utilize-Embedded-Languages.md) + - [选择语言](3-Advanced/Technical-Judgment/03-Choosing-Languages.md) + - 机智地妥协 + - [如何与时间压力作斗争](3-Advanced/Compromising-Wisely/01-How-to-Fight-Schedule-Pressure.md) + - [如何理解用户](3-Advanced/Compromising-Wisely/02-How-to-Understand-the-User.md) + - [如何获得晋升](3-Advanced/Compromising-Wisely/03-How-to-Get-a-Promotion.md) + - 服务你的团队 + - [如何发展才能](3-Advanced/Serving-Your-Team/01-How-to-Develop-Talent.md) + - [如何选择工作内容](3-Advanced/Serving-Your-Team/02-How-to-Choose-What-to-Work-On.md) + - [如何让你队友的价值最大化](3-Advanced/Serving-Your-Team/03-How-to-Get-the-Most-From-Your-Teammates.md) + - [如何划分问题](3-Advanced/Serving-Your-Team/04-How-to-Divide-Problems-Up.md) + - [如何处理无趣的问题](3-Advanced/Serving-Your-Team/05-How-to-Handle-Boring-Tasks.md) + - [如何为工程获取支持](3-Advanced/Serving-Your-Team/06-How-to-Gather-Support-for-a-Project.md) + - [如何发展一个系统](3-Advanced/Serving-Your-Team/07-How-to-Grow-a-System.md) + - [如何有效地沟通](3-Advanced/Serving-Your-Team/08-How-to-Communicate-Well.md) + - [如何告诉人们他们不想听的东西](3-Advanced/Serving-Your-Team/09-How-to-Tell-People-Things-They-Dont-Want-to-Hear.md) + - [如何处理管理神话](3-Advanced/Serving-Your-Team/10-How-to-Deal-with-Managerial-Myths.md) + - [如何处理混乱的组织](3-Advanced/Serving-Your-Team/11-How-to-Deal-with-Organizational-Chaos.md) +4. [词汇表](4-Glossary.md) +5. [附录 A - 书籍/网站](5-Bibliography.md) +6. [附录 B - 历史 (至2016年1月)](6-History.md) +6. [附录 C - 贡献 (至2016年1月)](7-Contributions.md) + + +Creative Commons License
How To Be A Programmer: Community Version by Robert L. Read with Community is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.