Craft programmer. Golden rules

    imageThis post is an excerpt from the "golden rules" from Peter Goodlif 's remarkable book, The Craft of a Programmer .

    Someone will refresh the memory, someone will be checked as with a check list, and someone will be interested and read a book. Because the post turned out to be quite voluminous, you can add it to your bookmarks and periodically return to it.

    Chapter 1. Holding the defense

    Do not make any assumptions. Assumptions that are not formally fixed often cause failures, especially as code grows.

    The more rush, the less speed. Always think what you are going to type from the keyboard.

    Do not believe anyone. Anyone, including yourself, can make mistakes in the logic of your program. You are suspicious of all inputs and outputs until you verify that they are valid.

    Compiler warnings help identify a ton of stupid errors. Always include their output. Keep your code compiled silently.

    Take care of all limited resources. Carefully organize their capture and release.

    Chapter 2. Subtle calculation

    Understand who will actually read your source code: other programmers. Write with the expectation of them.

    Find out what code standards are for your chosen language, and master each of them in practice. Assess the advantages and disadvantages of each.

    Choose one correct coding style and stick to it all the time.

    If your group has adopted a certain coding standard, stick to it. Leave your own favorite style.

    Say no to religious wars. Do not enter into them. Step aside.

    Chapter 3. What is in my name?

    Learn to give objects transparent names - they must clearly describe what is hidden behind them.

    To come up with a good name, the main thing is to clearly understand who it is intended for. Only in this case can the name become meaningful. If you can’t come up with a good name for the object, ask yourself if its purpose is clear.

    Learn the rules for creating names in the language you work with. More importantly, learn the idioms of this language. Are there standard ways to form names? So use them.

    Clarity of the name is preferable to its brevity.

    The relative merits of short and long names should be considered, especially depending on the scope of the variable.

    A naming rule that distinguishes between variable names and type names is preferable.

    Give the functions names from an external point of view, in the form of phrases expressing actions. Describe a logical operation, not a way to implement it.

    Avoid unnecessary words in the names. In particular, in type names - words such as class, data, object and type.

    Give namespaces and packages names that are logically related to content.

    Macros in C / C ++ are always capitalized to make them well visible, and their names are carefully chosen to avoid conflicts. Never capitalize other objects.

    Choose a consistent naming system and apply it consistently.

    The degree of detail required for a name depends on the context of its application. When creating names, consider contextual information.

    Chapter 4. Literary criticism

    Do not write code that needs external documentation. He is unreliable. Write code that is understandable without extraneous documentation.

    Write a code that a normal person can read without stress. The compiler will somehow cope.

    Avoid magic numbers. Use named constants.

    Important sections of the code should stand out against the general background and be easy to read. Hide everything that should not interest customers.

    Try to group related information. Make this grouping visual with language tools.

    Do not display meaningless error messages. Provide the most relevant information, depending on the context.

    Put comments in the code only if it is not possible to facilitate its understanding in other ways.

    Use competent documentation tools to automatically generate documentation for your code.

    Chapter 5. Margin Notes

    Learn to write as many comments as necessary. Give preference to quality over quantity.

    Take the trouble to ensure that your code does not require support in the form of a lot of comments.

    Good comments explain why, not how.

    One source for each fact. Do not copy the code in the comments.

    Finding yourself writing verbose comments describing your code, stop and think. Is this a sign that there is a certain problem of a higher order?

    Think what you write in the comments; Do not press thoughtlessly on the keys. Read the comment again in the context of the code. Does it contain information?

    Comments are part of the code. Arrange them so that the reading order is natural.

    Provide each source file with a prolog in the form of a comment.

    Comments should relate to the present, not the past. Do not describe what has changed, and do not talk about what happened before.

    If you changed the code, check the comments next to it.

    Chapter 6. People tend to make mistakes

    Error handling is a serious matter. The stability of your code depends on it.

    Do not leave the failed situation unattended. If you do not know how to deal with the problem, signal the failure to the calling code. Do not sweep the trash under the carpet in the hope that everything will somehow work out.

    Never neglect the error messages you receive. If there is a channel for error messages, then there are reasons for this.

    Handle all errors in the most favorable context when it becomes clear how to deal with it correctly.

    Ignoring errors does not save you time. You will spend more time figuring out the causes of incorrect program behavior than you would need to write an error handler.

    If you write code that may fail, write code at the same time to detect and handle errors. Do not put it off for the future. If you still have to postpone processing, at least write a snap-in to detect errors.

    Chapter 7. Programmer's Toolkit

    Learn your standard tools far and wide. The time you spend learning them will pay off immediately.

    Treat programming tools pragmatically; use them only if they make your life easier.

    Find out what kinds of tools exist. Find out where you can get them, even if you don’t need them at the moment.

    Each task has its own tool. Do not click nuts with a sledgehammer.

    Stay tuned for the latest versions of your tool, but be careful when updating.

    Choosing a code editor is critical; it has a huge impact on how you write code.

    Learn several languages. In each you will find a special way to solve problems. Consider them as a set of tools and choose the one that is most effective in a particular situation.

    Chapter 8. Testing Time

    Testing can reveal only the presence of errors. It cannot prove the absence of faults. Do not give in to a false sense of calm if the code has passed a number of inadequate tests.

    Test every piece of code you write. Do not expect someone else to do this for you.

    To make testing effective, it needs to be started in advance when the detected errors cannot yet do much harm. Test code can be written earlier than working!

    Write tests for all errors identified.

    Run your tests as often as possible.

    Reading the code is very easy to deceive and believe that it works correctly. If you wrote the code, then when you read it, you will see what you were going to write, and not what you actually wrote. Learn to read the code with cynical distrust.

    Write a complete set of tests, each of which will test a specific aspect of the code. Fifteen tests that show the same error are less useful than 15 tests that show 15 different errors.

    The code architecture should make it easier to test.

    Automate code testing as much as possible. This is faster and easier than doing the tests manually, and much more reliable: it is more likely that the tests will run regularly.

    Perform testing automatically during the build procedure.

    Chapter 9. Troubleshooting

    Compile the code when the compiler displays all warning messages. Thus, you will discover potential problems before you encounter them in reality.

    Follow the golden rule of debugging: think with your head.

    Set a reasonable time limit for “unsystematic” debugging, and if it is unsuccessful, switch to a more methodical method.

    Examine debugged code - it's hard to find errors in code that you don’t understand.

    When you are looking for a mistake, disbelieve anyone. Check the most incredible reasons, instead of immediately rejecting them. Do not take anything for granted.

    If the product build fails, look at the first compiler error. Subsequent posts are far less credible.

    Debugging is a methodical work, slowly narrowing the ring around the location of the error. You should not treat it like a game in the next game.

    The first step in establishing the place of an error is to determine how to confidently reproduce it.

    Start from a known place, for example, from the point of abnormal termination of a program. Then move in the opposite direction to the cause of the failure.

    If it seemed to you that you found the cause of the error, thoroughly examine it and make sure that you did not make a mistake. Do not recklessly accept the very first hypothesis.

    Debugging ends only when you prove that the error is resolved and the problem is resolved forever.

    Use extreme caution when correcting errors. Make sure that your modification does not cripple anything else.

    Correcting the error, check if it repeats itself in close sections of the code. Eliminate the error once and for all: correct all its duplicates immediately.

    From each corrected error, draw conclusions. Could it have been avoided? Could it be detected faster?

    Faced with behaviors that you cannot explain, use debuggers moderately. Don't get used to rushing at them right away without first trying to figure out how your code works.

    Chapter 10. The Code Jack Built

    Consider the build system as part of the source tree and maintain them together. They are closely related.

    All programmers involved in the project must use a single build system. Otherwise, they will all compile different software packages.

    The correct build system allows you to repeatedly create physically identical binary files.

    You should be able to get the source tree three years ago and correctly assemble it again.

    The correct system looks like one operation. It is enough to press a button or execute one command.

    For each assembly rule, write an appropriate cleaning rule that cancels the entire operation.

    Organize an automated build procedure for your software product. Check with its help the operability of your code.

    Final builds are always performed from clean source code. Make sure that later you can always get this clean source code from an archive or version control system.

    Test the final configuration of your application, not just production builds. Small differences between them can adversely affect code behavior.

    Chapter 11. Thirst for Speed

    You need to think about the effectiveness of the program from the very beginning - do not hope that at the end of development you will be able to increase it at the cost of small changes.

    The correctness of the code is much more important than its speed. What is the use of quickly obtaining a result if it is incorrect!

    Consider alternatives to optimization; will you be able to improve the effectiveness of the program in other ways?

    Find out if there really is a need to optimize the code, but it's better to write effective, high-quality code from the very beginning.

    Optimize the code separately from any other work so that the results of one work do not affect another.

    Optimize final versions of the program, not intermediate builds.

    Carefully select the input for profiling so that it reflects the real world. Otherwise, it may turn out that you are optimizing those parts of the program that are not normally executed.

    Do not limit yourself to the profiler when searching for reasons for the lack of effectiveness of the program; they may be deeper.

    Be sure to take measurements before and after optimization.

    It is better to replace a slow algorithm with a fast one than to try to improve the implementation of an existing algorithm.

    Chapter 12. Insecurity Complex

    Keep in mind what important resources you have. Do you have particularly sensitive information or special features that you can hunt for? Protect them.

    The more complex a computer system, the more likely it is that there are gaps in its security system. Therefore, write as simple software as possible!

    Do not pass by vulnerabilities and do not consider yourself invincible. Somewhere there is someone who is trying to apply an exploit to your code.

    Run only programs from trusted sources on your computer. Establish a clear policy for determining the reliability of sources.

    Security is an important aspect of the architecture of any software product. It would be a mistake not to take care of it in the early stages of development.

    When designing a program, rely only on well-known, secure third-party components.

    Get ready for your system to be attacked, and design all parts of it with this in mind.

    Chapter 13. The Importance of Design

    Programming is design work. This is a creative and artistic act, not a mechanical coding.

    Think before knocking on keys; make an understandable project. Otherwise, you will get chaos, not a code.

    Less is better. Your goal should be a simple code that, with a small size, solves big problems.

    Making a simple thing is difficult. If the code structure seems obvious, you should not think that it was given without difficulty.

    Design modules that are internally connected and minimally interconnected. Decomposition should reflect the correct division of the task into parts.

    Draw a line that no one should cross: define clear APIs and interfaces.

    Design taking into account the subsequent expansion, but do not overdo it, otherwise you will not write a program, but an OS.

    Do it once. Do well. Avoid duplication.

    Solve code portability issues at the design stage, rather than by reworking your finished code.

    Be pragmatic about design tools and methodologies: use them when it’s really useful, but don’t become their slaves.

    Chapter 14. Software Architecture

    Architecture has the biggest impact on the design and further development of a software system. For this reason, it is important to correctly determine it in the very early stages of development.

    Keep a description of the system architecture in a place where it is available to everyone who might need it: the programmer responsible for maintenance and installation, managers, and possibly customers.

    An architecture specification is an important tool for reporting the status of your system. Make sure that it matches the state of the software.

    Take all design decisions for a software product in the context of architecture. Be careful not to deviate from systemic vision and strategy. Do not make small, irrelevant changes.

    Good system architecture should be simple. A description consisting of one paragraph and one simple diagram is sufficient.

    Architecture defines the most important components of the system and their interaction. She does not describe their device.

    Good architecture leaves room for maneuver, expansion, modification. But her community does not cross reasonable boundaries.

    Understand the basic architectural styles and evaluate their advantages and disadvantages. This will help you to be more sympathetic to the software products you come across, and to properly design the systems.

    Chapter 15. Software — Evolution or Revolution?

    Remember how easily modifiable code degrades. Avoid modifications after which the system is in worse condition.

    Learn to detect broken code. Examine its symptoms and handle decomposed code with extreme caution.

    Be honest about writing code. Good programmers think about how their code will look in a few years, and not how much effort they will need to make today.

    Write a new code taking into account the possible need to modify it in the future. Make it clear, extensible, and simple.

    Use caution when modifying. Be aware of whether someone is modifying nearby code.

    Talk about dangerous changes, especially when preparing to release a new version. Even the simplest modifications can disrupt the operation of other code.

    Do not smack the code thoughtlessly. Stop and ponder what you are doing.

    Carefully test all your modifications, no matter how simple they may be. It is very easy to miss a stupid mistake.

    Chapter 16. Encoders

    Find out what type of programmers you are. Determine how you can make good use of your good qualities and compensate for the bad ones.

    Chapter 17. Together We Are Power

    The ability to work in a team is an important quality of a highly qualified software developer.

    The resulting code is affected both by relationships within the team and by external contacts. Watch how they affect your work.

    Organize your team in accordance with the code that you are going to build, and not vice versa - code in accordance with the existing team.

    The presence of channels for effective communication is vital for the normal work of the team. Such channels need to be organized and maintained. A good programmer should be able to communicate well.

    None of the programmers own any piece of code. Each of the participants has access to the entire code and can modify it as needed.

    Successful teams develop and work purposefully; their occurrence cannot be attributed to chance.

    Do not lose information when people leave the team. Organize its transfer and receive from them all the important data, including code documentation, testing tools and maintenance instructions.

    Chapter 18. Protecting Source Code

    The code is valuable. Treat him with respect and care.

    Version control system is an important software development tool. It is necessary for reliable team work.

    Pay attention to the repository. Be careful not to write inactive code that will not allow other developers to work.

    Back up your data. Develop recovery strategies without waiting for disaster to break out.

    Chapter 19. Specifications

    The software development process needs not just specifications, but their high quality.

    Specifications are an important communication mechanism between software developers. They serve to record information that should not be lost or forgotten.

    Software requirements must be set in advance so that unnecessary expectations do not arise, to impede the expansion of functionality and reduce developer anxiety.

    If your programming task is not clearly defined, do not start coding without writing a specification and agreeing it.

    Use competent programming tools to compile technical documentation. Do not write in a text editor a document that quickly becomes obsolete.

    When compiling a specification, consider its contents. Choose a structure and vocabulary that are understandable to the audience, and make sure that the document is correct, complete and contains its own description.

    Avoiding drafting specifications is dangerous and unprofessional. If you don’t have enough time to write specifications, it is probably not enough to write code either.

    Chapter 20. Review of the shooting

    Code reviewing is an excellent tool for finding and eliminating hidden errors, improving the quality of the code, strengthening collective responsibility for the code and disseminating knowledge.

    When creating a system, find out if you need to review, and if so, what code.

    Carefully select the code for reviewing. If you cannot review the entire code, make an informed choice. No need to pick at random and waste precious time.

    No matter who writes the code, it is subject to peer review and careful study by colleagues. Get a review of your code.

    The success of reviewing is highly dependent on the positive position of the author and reviewers. The purpose of the review is to jointly improve the code, and not to identify the perpetrators or justify decisions made during implementation.

    If you do not know what good code should look like, you cannot reasonably judge the quality of work of other programmers.

    Chapter 21. How long is the rope?

    Estimating the duration of a software product development is a factual guess. For each assessment, there is some measure of your confidence in it.

    Estimating software development time is a really difficult task. Avoid underestimating the amount of work ahead. Consider the possible consequences of an incorrect assessment.

    Everyone (including you) wants shorthand schedules. Do not be fooled about what really can be done in the time allotted to you. Do not make unrealistic promises when you need to provide code that is ready for delivery.

    Time estimates need to be applied to small tasks whose workload is easy to understand. The unit of measurement should be man-hours or man-days.

    Distinguish whose work you are evaluating in terms of time: your own (on a system that you understand well) or someone else's (one who may need to study the system).

    Do not assess alone. Find out the opinions of other people to clarify your ratings.

    Schedule your work so that you have time to clean up your code. Plan for returning technical debt.

    Constantly check your progress with the plan. Then there will not be a sudden lag.

    Chapter 22. The recipe for the program

    Good programmers know how to program - they know the methods and techniques of work.

    Our software projects are determined by the styles and processes that we apply. They inevitably affect the form and quality of the code.

    Without a development process, the team is in a state of anarchy. Programs appear due to luck, and not as a result of targeted actions.

    The choice of prescription program can be determined by many reasons, which should be good. The motivation for your choice says a lot about how mature your organization is.

    The process that you accept should not be too formal and difficult to implement. Usually signs of a good process are just the opposite characteristics. However, a certain process should be.

    Choosing a process is vital. Unsuccessful projects in most cases are not for technical reasons. Almost always, one of the main reasons is the poor organization of the process.

    Chapter 23. Beyond the Possible

    There are different types of programming in various subject areas. Each area has its own special problems and requires specific skills and experience.

    Know your programming area. Learn its specifics. Learn to write great programs that suit her needs.

    Chapter 24. What Next?

    To become a good programmer, you need to choose the right position - the angle from which the creation of software is considered.

    Improve your skills. Do not lose the love of programming and the desire to be a master at it.

    Also popular now: