Skip to content

Commit

Permalink
Added original version
Browse files Browse the repository at this point in the history
  • Loading branch information
Semigradsky committed Dec 23, 2014
1 parent 512e5b2 commit 35b95cd
Show file tree
Hide file tree
Showing 99 changed files with 2,224 additions and 4 deletions.
4 changes: 3 additions & 1 deletion LANGS.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
* [English](en)
* [русский язык](ru)
<!--
* [русский язык](ru)
-->
4 changes: 3 additions & 1 deletion en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

This is a [GitBook](https://www.gitbook.io) version of the ['97 Things Every Programmer Should Know' project](http://programmer.97things.oreilly.com/wiki/index.php/97_Things_Every_Programmer_Should_Know).

All content is licensed under the [Creative Commons Attribution Non Commercial Share Alike 3.0 license](http://creativecommons.org/licenses/by-nc-sa/3.0/). Print versions of the book are available on [Amazon.com](http://www.amazon.com/Things-Every-Programmer-Should-Know/dp/0596809484).
All content is licensed under the [Creative Commons Attribution Non Commercial Share Alike 3.0 license](http://creativecommons.org/licenses/by-nc-sa/3.0/). Print versions of the book are available on [Amazon.com](http://www.amazon.com/Things-Every-Programmer-Should-Know/dp/0596809484).

If you find a mistakes or do you have any suggestions, you can [create issue](https://github.com/Semigradsky/97-things-every-programmer-should-know/issues) or [pull request](https://github.com/Semigradsky/97-things-every-programmer-should-know/pulls) to [repository](https://github.com/Semigradsky/97-things-every-programmer-should-know).
96 changes: 95 additions & 1 deletion en/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,98 @@
* [Introduction](README.md)
* [Act with Prudence](/thing_01/README.md)
* [Apply Functional Programming Principles](thing_02/README.md)

* [Ask "What Would the User Do?" (You Are not the User)](thing_03/README.md)
* [Automate Your Coding Standard](thing_04/README.md)
* [Beauty Is in Simplicity](thing_05/README.md)
* [Before You Refactor](thing_06/README.md)
* [Beware the Share](thing_07/README.md)
* [The Boy Scout Rule](thing_08/README.md)
* [Check Your Code First before Looking to Blame Others](thing_09/README.md)
* [Choose Your Tools with Care](thing_10/README.md)
* [Code in the Language of the Domain](thing_11/README.md)
* [Code Is Design](thing_12/README.md)
* [Code Layout Matters](thing_13/README.md)
* [Code Reviews](thing_14/README.md)
* [Coding with Reason](thing_15/README.md)
* [A Comment on Comments](thing_16/README.md)
* [Comment Only What the Code Cannot Say](thing_17/README.md)
* [Continuous Learning](thing_18/README.md)
* [Convenience Is not an -ility](thing_19/README.md)
* [Deploy Early and Often](thing_20/README.md)
* [Distinguish Business Exceptions from Technical](thing_21/README.md)
* [Do Lots of Deliberate Practice](thing_22/README.md)
* [Domain-Specific Languages](thing_23/README.md)
* [Don't Be Afraid to Break Things](thing_24/README.md)
* [Don't Be Cute with Your Test Data](thing_25/README.md)
* [Don't Ignore that Error!](thing_26/README.md)
* [Don't Just Learn the Language, Understand its Culture](thing_27/README.md)
* [Don't Nail Your Program into the Upright Position](thing_28/README.md)
* [Don't Rely on "Magic Happens Here"](thing_29/README.md)
* [Don't Repeat Yourself](thing_30/README.md)
* [Don't Touch that Code!](thing_31/README.md)
* [Encapsulate Behavior, not Just State](thing_32/README.md)
* [Floating-point Numbers Aren't Real](thing_33/README.md)
* [Fulfill Your Ambitions with Open Source](thing_34/README.md)
* [The Golden Rule of API Design](thing_35/README.md)
* [The Guru Myth](thing_36/README.md)
* [Hard Work Does not Pay Off](thing_37/README.md)
* [How to Use a Bug Tracker](thing_38/README.md)
* [Improve Code by Removing It](thing_39/README.md)
* [Install Me](thing_40/README.md)
* [Inter-Process Communication Affects Application Response Time](thing_41/README.md)
* [Keep the Build Clean](thing_42/README.md)
* [Know How to Use Command-line Tools](thing_43/README.md)
* [Know Well More than Two Programming Languages](thing_44/README.md)
* [Know Your IDE](thing_45/README.md)
* [Know Your Limits](thing_46/README.md)
* [Know Your Next Commit](thing_47/README.md)
* [Large Interconnected Data Belongs to a Database](thing_48/README.md)
* [Learn Foreign Languages](thing_49/README.md)
* [Learn to Estimate](thing_50/README.md)
* [Learn to Say "Hello, World"](thing_51/README.md)
* [Let Your Project Speak for Itself](thing_52/README.md)
* [The Linker Is not a Magical Program](thing_53/README.md)
* [The Longevity of Interim Solutions](thing_54/README.md)
* [Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly](thing_55/README.md)
* [Make the Invisible More Visible](thing_56/README.md)
* [Message Passing Leads to Better Scalability in Parallel Systems](thing_57/README.md)
* [A Message to the Future](thing_58/README.md)
* [Missing Opportunities for Polymorphism](thing_59/README.md)
* [News of the Weird: Testers Are Your Friends](thing_60/README.md)
* [One Binary](thing_61/README.md)
* [Only the Code Tells the Truth](thing_62/README.md)
* [Own (and Refactor) the Build](thing_63/README.md)
* [Pair Program and Feel the Flow](thing_64/README.md)
* [Prefer Domain-Specific Types to Primitive Types](thing_65/README.md)
* [Prevent Errors](thing_66/README.md)
* [The Professional Programmer](thing_67/README.md)
* [Put Everything Under Version Control](thing_68/README.md)
* [Put the Mouse Down and Step Away from the Keyboard](thing_69/README.md)
* [Read Code](thing_70/README.md)
* [Read the Humanities](thing_71/README.md)
* [Reinvent the Wheel Often](thing_72/README.md)
* [Resist the Temptation of the Singleton Pattern](thing_73/README.md)
* [The Road to Performance Is Littered with Dirty Code Bombs](thing_74/README.md)
* [Simplicity Comes from Reduction](thing_75/README.md)
* [The Single Responsibility Principle](thing_76/README.md)
* [Start from Yes](thing_77/README.md)
* [Step Back and Automate, Automate, Automate](thing_78/README.md)
* [Take Advantage of Code Analysis Tools](thing_79/README.md)
* [Test for Required Behavior, not Incidental Behavior](thing_80/README.md)
* [Test Precisely and Concretely](thing_81/README.md)
* [Test While You Sleep (and over Weekends)](thing_82/README.md)
* [Testing Is the Engineering Rigor of Software Development](thing_83/README.md)
* [Thinking in States](thing_84/README.md)
* [Two Heads Are Often Better than One](thing_85/README.md)
* [Two Wrongs Can Make a Right (and Are Difficult to Fix)](thing_86/README.md)
* [Ubuntu Coding for Your Friends](thing_87/README.md)
* [The Unix Tools Are Your Friends](thing_88/README.md)
* [Use the Right Algorithm and Data Structure](thing_89/README.md)
* [Verbose Logging Will Disturb Your Sleep](thing_90/README.md)
* [WET Dilutes Performance Bottlenecks](thing_91/README.md)
* [When Programmers and Testers Collaborate](thing_92/README.md)
* [Write Code as If You Had to Support It for the Rest of Your Life](thing_93/README.md)
* [Write Small Functions Using Examples](thing_94/README.md)
* [Write Tests for People](thing_95/README.md)
* [You Gotta Care about the Code](thing_96/README.md)
* [Your Customers Do not Mean What They Say](thing_97/README.md)
2 changes: 1 addition & 1 deletion en/thing_01/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Act with Prudence

*"Whatever you undertake, act with prudence and consider the consequences" Anon*
> *"Whatever you undertake, act with prudence and consider the consequences" Anon*
No matter how comfortable a schedule looks at the beginning of an iteration, you can't avoid being under pressure some of the time. If you find yourself having to choose between "doing it right" and "doing it quick" it is often appealing to "do it quick" on the understanding that you'll come back and fix it later. When you make this promise to yourself, your team, and your customer, you mean it. But all too often the next iteration brings new problems and you become focused on them. This sort of deferred work is known as technical debt and it is not your friend. Specifically, Martin Fowler calls this deliberate technical debt in his [taxonomy of technical debt](http://martinfowler.com/bliki/TechnicalDebtQuadrant.html), which should not be confused with inadvertent technical debt.

Expand Down
16 changes: 16 additions & 0 deletions en/thing_03/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Ask "What Would the User Do?" (You Are not the User)

We all tend to assume that other people think like us. But they don't. Psychologists call this the false consensus bias. When people think or act differently to us, we're quite likely to label them (subconsciously) as defective in some way.

This bias explains why programmers have such a hard time putting themselves in the users' position. Users don't think like programmers. For a start, they spend much less time using computers. They neither know nor care how a computer works. This means they can't draw on any of the battery of problem-solving techniques so familiar to programmers. They don't recognize the patterns and cues programmers use to work with, through, and around an interface.

The best way to find out how users think is to watch one. Ask a user to complete a task using a similar piece of software to what you're developing. Make sure the task is a real one: "Add up a column of numbers" is OK; "Calculate your expenses for the last month" is better. Avoid tasks that are too specific, such as "Can you select these spreadsheet cells and enter a *SUM* formula below?" — there's a big clue in that question. Get the user to talk through his or her progress. Don't interrupt. Don't try to help. Keep asking yourself "Why is he doing that?" and "Why is she not doing that?"

The first thing you'll notice is that users do a core of things similarly. They try to complete tasks in the same order — and they make the same mistakes in the same places. You should design around that core behavior. This is different from design meetings, where people tend to be listened to for saying "What if the user wants to...?" This leads to elaborate features and confusion over what users want. Watching users eliminates this confusion.

You'll see users getting stuck. When you get stuck, you look around. When users get stuck, they narrow their focus. It becomes harder for them to see solutions elsewhere on the screen. It's one reason why help text is a poor solution to poor user interface design. If you must have instructions or help text, make sure to locate it right next to your problem areas. A user's narrow focus of attention is why tool tips are more useful than help menus.

Users tend to muddle through. They'll find a way that works and stick with it no matter how convoluted. It's better to provide one really obvious way of doing things than two or three shortcuts.
You'll also find that there's a gap between what users say they want and what they actually do. That's worrying as the normal way of gathering user requirements is to ask them. It's why the best way to capture requirements is to watch users. Spending an hour watching users is more informative than spending a day guessing what they want.

by [Giles Colborne](http://programmer.97things.oreilly.com/wiki/index.php/Giles_Colborne)
20 changes: 20 additions & 0 deletions en/thing_04/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Automate Your Coding Standard

You've probably been there too. At the beginning of a project, everybody has lots of good intentions — call them "new project's resolutions." Quite often, many of these resolutions are written down in documents. The ones about code end up in the project's coding standard. During the kick-off meeting, the lead developer goes through the document and, in the best case, everybody agrees that they will try to follow them. Once the project gets underway, though, these good intentions are abandoned, one at a time. When the project is finally delivered the code looks like a mess, and nobody seems to know how it came to be this way.

When did things go wrong? Probably already at the kick-off meeting. Some of the project members didn't pay attention. Others didn't understand the point. Worse, some disagreed and were already planning their coding standard rebellion. Finally, some got the point and agreed but, when the pressure in the project got too high, they had to let something go. Well-formatted code doesn't earn you points with a customer that wants more functionality. Furthermore, following a coding standard can be quite a boring task if it isn't automated. Just try to indent a messy class by hand to find out for yourself.

But if it's such a problem, why is that we want to have a coding standard in the first place? One reason to format the code in a uniform way is so that nobody can "own" a piece of code just by formatting it in his or her private way. We may want to prevent developers using certain anti-patterns, in order to avoid some common bugs. In all, a coding standard should make it easier to work in the project, and maintain development speed from the beginning to the end. It follows then that everybody should agree on the coding standard too — it does not help if one developer uses three spaces to indent code, and another one four.

There exists a wealth of tools that can be used to produce code quality reports and to document and maintain the coding standard, but that isn't the whole solution. It should be automated and enforced where possible. Here are a few examples:

- Make sure code formatting is part of the build process, so that everybody runs it automatically every time they compile the code.
- Use static code analysis tools to scan the code for unwanted anti-patterns. If any are found, break the build.
- Learn to configure those tools so that you can scan for your own, project-specific anti-patterns.
- Do not only measure test coverage, but automatically check the results too. Again, break the build if test coverage is too low.

Try to do this for everything that you consider important. You won't be able to automate everything you really care about. As for the things that you can't automatically flag or fix, consider them to be a set of guidelines supplementary to the coding standard that is automated, but accept that you and your colleagues may not follow them as diligently.

Finally, the coding standard should be dynamic rather than static. As the project evolves, the needs of the project change, and what may have seemed smart in the beginning, isn't necessarily smart a few months later.

By [Filip van Laenen](http://programmer.97things.oreilly.com/wiki/index.php/Filip_van_Laenen)
27 changes: 27 additions & 0 deletions en/thing_05/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Beauty Is in Simplicity

There is one quote that I think is particularly good for all software developers to know and keep close to their hearts:

> *Beauty of style and harmony and grace and good rhythm depends on simplicity.* — Plato
In one sentence I think this sums up the values that we as software developers should aspire to.

There are a number of things we strive for in our code:

- Readability
- Maintainability
- Speed of development
- The elusive quality of beauty

Plato is telling us that the enabling factor for all of these qualities is simplicity.

What is beautiful code? This is potentially a very subjective question. Perception of beauty depends heavily on individual background, just as much of our perception of anything depends on our background. People educated in the arts have a different perception of (or at least approach to) beauty than people educated in the sciences. Arts majors tend to approach beauty in software by comparing software to works of art, while science majors tend to talk about symmetry and the golden ratio, trying to reduce things to formulae. In my experience, simplicity is the foundation of most of the arguments from both sides.

Think about source code that you have studied. If you haven't spent time studying other people's code, stop reading this right now and find some open source code to study. Seriously! I mean it! Go search the web for some code in your language of choice, written by some well-known, acknowledged expert.

You're back? Good. Where were we? Ah yes... I have found that code that resonates with me and that I consider beautiful has a number of properties in common. Chief among these is simplicity. I find that no matter how complex the total application or system is, the individual parts have to be kept simple. Simple objects with a single responsibility containing similarly simple, focused methods with descriptive names. Some people think the idea of having short methods of five to ten lines of code is extreme, and some languages make it very hard to do this, but I think that such brevity is a desirable goal nonetheless.

The bottom line is that beautiful code is simple code. Each individual part is kept simple with simple responsibilities and simple relationships with the other parts of the system. This is the way we can keep our systems maintainable over time, with clean, simple, testable code, keeping the speed of development high throughout the lifetime of the system.
Beauty is born of and found in simplicity.

By Jørn Ølmheim
19 changes: 19 additions & 0 deletions en/thing_06/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Before You Refactor

At some point every programmer will need to refactor existing code. But before you do so please think about the following, as this could save you and others a great deal of time (and pain):

- *The best approach for restructuring starts by taking stock of the existing codebase and the tests written against that code.* This will help you understand the strengths and weaknesses of the code as it currently stands, so you can ensure that you retain the strong points while avoiding the mistakes. We all think we can do better than the existing system... until we end up with something no better — or even worse — than the previous incarnation because we failed to learn from the existing system's mistakes.

- *Avoid the temptation to rewrite everything.* It is best to reuse as much code as possible. No matter how ugly the code is, it has already been tested, reviewed, etc. Throwing away the old code — especially if it was in production — means that you are throwing away months (or years) of tested, battle-hardened code that may have had certain workarounds and bug fixes you aren't aware of. If you don't take this into account, the new code you write may end up showing the same mysterious bugs that were fixed in the old code. This will waste a lot of time, effort, and knowledge gained over the years.

- *Many incremental changes are better than one massive change.* Incremental changes allows you to gauge the impact on the system more easily through feedback, such as from tests. It is no fun to see a hundred test failures after you make a change. This can lead to frustration and pressure that can in turn result in bad decisions. A couple of test failures is easy to deal with and provides a more manageable approach.

- *After each iteration, it is important to ensure that the existing tests pass.* Add new tests if the existing tests are not sufficient to cover the changes you made. Do not throw away the tests from the old code without due consideration. On the surface some of these tests may not appear to be applicable to your new design, but it would be well worth the effort to dig deep down into the reasons why this particular test was added.

- *Personal preferences and ego shouldn't get in the way.* If something isn't broken, why fix it? That the style or the structure of the code does not meet your personal preference is not a valid reason for restructuring. Thinking you could do a better job than the previous programmer is not a valid reason either.

- *New technology is insufficient reason to refactor.* One of the worst reasons to refactor is because the current code is way behind all the cool technology we have today, and we believe that a new language or framework can do things a lot more elegantly. Unless a cost–benefit analysis shows that a new language or framework will result in significant improvements in functionality, maintainability, or productivity, it is best to leave it as it is.

- *Remember that humans make mistakes.* Restructuring will not always guarantee that the new code will be better — or even as good as — the previous attempt. I have seen and been a part of several failed restructuring attempts. It wasn't pretty, but it was human.

by [Rajith Attapattu](http://programmer.97things.oreilly.com/wiki/index.php/Rajith_Attapattu)
Loading

0 comments on commit 35b95cd

Please sign in to comment.