《Code Reading》读书笔记

Code Reading: The Open Source Perspective

作者: Diomidis Spinellis

If you are a programmer, you need this book.

 

首先看附录,理解附录E中的每句话,以此检验是否理解了每一章内容。如果不能理解,请立刻回头仔细阅读,直到理解为止。

 

You've got a day toadd a new feature in a 34,000-line program: Where do you start? Page 333

你有一天

How can you understand and simplify an inscrutable(adj.难以理解的) piece of code? Page 39

 

Where do you start when disentangling(解开)a complicated build process? Page 167

 

How do you comprehend code that appears to bedoing five things in parallel? Page 132

 

 

You may read code because you have to-to fix(修复) it, inspect(检查)it, or improve(改进) it. You may read code the way(用...方法) an engineer examines a machine--todiscover what makes it tick(v.运作). Or you mayread code because you are scavenging(净化)--looking for material to reuse.

 

Code-reading requires its own set of skills, andthe ability to determine which technique you use when is crucial. In thisindispensable(绝对必要的) book, Diomidis Spinellis uses more than 600 real-worldexamples to show you how to identify good (and bad) code: how to read it, whatto look for, and how to use this knowledge to improve your own code.

Fact: If you make a habit ofreading good code, you will write better code yourself.

 

Foreword(前言)

No, we deliver by writing code: code is reality.

只教写代码而不教读代码是 one of the biggest tragedies(悲剧) inthe industry(行业).

Because the way to learn to writegreat code is by reading code.

The irony(n.讽刺,反话) is thatthere's never been a better time to read code.

开放源代码社区给我们大量的源代码去阅读。

Code reading is fun(有趣的). I loveto read others' code. I read it to learn tricks and to study traps.

I sometimes read code for thenarrative(叙述性的), like a book you'd pick up at an airport before a long flight.把读代码当作读小说!

Sometimes I read code more critically(精密的).

In fact, code reading is one ofthe most effective ways to eliminate problems in programs.

Half of the time we spend onsoftware is used looking at existing code:

There's a bug in a 100,000-lineprogram, and you've got an hour to find it. How do you start?

pragmatic adj.注重实效的

exotic adj.外来的

And it stresses the importance oftool building: write code to help you read code.

 

Praface(序言)

What do we ever(究竟) get nowadaysfrom reading to equal the excitement(兴奋) and the revelation(启示) in those firstfourteen years?

我们今天究竟从阅读中得到什么才比得上过去14年中的兴奋和启示呢?

-Graham Greene

The reading of code is likely tobe one of the most common(平常的) activities of a computing professional, yet itis seldom taught as a subject or formally used as a method forlearning how to design and program.

 

proprietary adj.私人拥有的

spur vt.鞭策, 刺激

bootleg adj.非法制造的 vt.违法制造

photocopy n.影印版

My goal was to provide background(基本的)knowledge and techniques for reading code written by others.

inevitable adj.不可避免的

peer n.伙伴,同等的人

 

阅读代码是学习设计和编程的最好方法,但是现实世界或者高质量的代码太少,让人没东西可读。现在开放源代码的出现,使人们有了大量的好代码去阅读。本书的目的是告诉人们重视代码阅读,让学生从开放源代码中好好学习。

 

Supplementary Material 辅助材料

superb adj.极好的

condemnable adj.该受责备的

counterexample n.反例

 

I selected NetBSD over othersimilarly admirable and very popular free Unix-like systems (such as GNU/Linux,FreeBSD, and OpenBSD) because the primary goal of the NetBSD project is to emphasizecorrect design and well-written code.

the least common denominator最小公分母

I appreciate that ... 我意识到...

Often the code I am using as a counterexample is alame duck, as it was written at a time whentechnological and other restrictions justified(证明...是正当的) the particular coding(编码)practice(习惯), or the particular practice is criticized out of(脱离) the context(环境).

 

Acknowledgments 感谢

 

Chapter 1. Introduction

and they are entirely(完全地) free(无...的) of any sort(有几分地)of comments or documentation.

他们完全没有任何注释和文档。

unrelenting adj.无情的

However, 40% to 70% of the effort that goes into asoftware system is expended after the system is first written. That effortinvariably involves reading, understanding, and modifying the original code.

outsourcing n.外购

and the rising(上涨的) importance of open-sourcedevelopment efforts(成就) and cooperative(协作的) development processes(过程)(including outsourcing, code walkthroughs预排, and extreme programming) make codereading an essential skill for today's software engineer. 使成为如今软件工程师的一项基本技能

 

Having mastered(精通) the book's contents, you will:

Be able to read and understand nontrivial(重要的)software code

Appreciate(领会) many important software developmentconcepts

Know how to explore large bodies of code

Have a reading capability of a multitude(大多数) ofimportant high- and low-level programming languages

Appreciate(体会到) the intricacies(n.复杂) of realsoftware projects

 

1.1 Why and How to Read Code

1.1.1 Code as Literature

Dick Gabriel makes the point that ours is one ofthe few creative professions(职业) in which writers are not allowed to read eachother's work.

Dick Gabriel指出,我们的职业是不允许不允许作者读互相的作品为数不多之一。

Make it a habit to spend time reading high-qualitycode that others have written.阅读好代码好处多多!

 

读代码之前先判断代码是不是优秀的,值不值得去读!

 

Read code selectively and with a goalin your mind. Are you trying to learn new patterns, a coding style, a way to satisfysome requirements? Alternatively, you may find yourself browsing code to pickup random gems. In that case, be ready to study in detail interesting parts youdon't know: language features (even if you know a language in depth, modernlanguages evolve with new features), APIs, algorithms, data structures,architectures, and design patterns.

peculiar adj.特殊的

concurrent(一致的) versions system (CVS)

1.1.2 Code as Exemplar

Exemplar n.榜样

 

monopolize vt.独占, 垄断

exhilarating adj.令人愉快的

thoroughly adv.彻底地

elusive adj.难懂的

intractable adj.难处理的

wary adj.机警的

我们读代码为了:

fixing 、inspecting,  improving existing code、learn how somethingworks、reuse 、purely(纯粹地) for your own pleasure。

对于每种目的都有不同的代码阅读技巧。

 

imperatives n.规则

critique vt.批评

 

You can easily discern(辨别) code of low quality bythe following signs:

 

An inconsistent coding style

A gratuitously complicated or unreadable structure

Obvious logical errors or omissions

Overuse of nonportable constructs

Lack of maintenance

 

You should not, however, expect to learn soundprogramming from poorly written code;

无论如何,你不应当期望从写的很糟糕的代码中学到充分的编程技术。

 

在阅读之前先问自己,当前的是否是最好的版本,因为在大多数情况下新版本在结构和功能上都比老版本有所提高。

reverse engineering 逆向工程

 

Sometimes you may find yourself reading code froman environment completely foreign(陌生的) to you(computer language, operating system, or API). Given a basic familiarity withprogramming and the underlying computer science concepts, you can in many casesuse source code as a way to teach yourself the basics of the new environment.However, start your reading with small programs; do not immediately dive intothe study of a large system. Build the programs you study and run them. Thiswill provide you with both immediate feedback on the way the code is supposedto work and a sense of achievement. The next step involves actively changingthe code to test your understanding. Again, begin with small changes andgradually increase their scope. Your active involvement with real code canquickly teach you the basics of the new environment. Once you think you havemastered them, consider investing some effort (and possibly some cash) to learnthe environment in a more structured way. Read related books, documentation, ormanual pages, or attend training courses; the two methods of learningcomplement each other.

 

One other way in which you can actively readexisting code as literature entails improving it. In contrast to other literalworks, software code is a live artifact that is constantly improved. If the code is valuable to you or your community, thinkabout how you could improve it. This can involve using a better design oralgorithm, documenting some code parts, or adding functionality. Open-sourcecode is often not well documented; consider reinvesting your understanding ofthe code in improved documentation. When working on existing code, coordinateyour efforts with the authors or maintainers to avoid duplication of work orbad feelings. If your changes are likely to be substantial, think aboutbecoming a concurrent versions system (CVS) committer-an individual with theauthority to directly commit code to a project's source base. Consider thebenefits you receive from open-source software to be a loan; look for ways torepay it by contributing back to the open-source community.

 

1.1.2 Code as Exemplar

There are cases where you might find yourself wondering how a specific functionality is realized.For some application classes you may be able to find an answer to your questionsin standard textbooks or specialized publications and research articles.

 

The key concept when you are using code asexemplar is to be flexible.Be prepared to use anumber of different strategies and approaches to understand how the code works.Start with any documentation you might find (see Chapter 8). A formal softwaredesign document would be ideal, but even user documentation can be helpful.Actually use the system to get a feeling of its external interfaces. Understandwhat exactly are you actually looking for: a system call, an algorithm, a codesequence, an architecture? Devise a strategy that will uncover your target.Different search strategies are effective for different purposes. You may needto trace through the instruction execution sequence, run the program and placea breakpoint in a strategic location, or textually search through the code tofind some specific code or data elements. Tools (see Chapter 10) will help youhere, but do not let one of them monopolize your attention. If a strategy does not quickly produce the results you want,drop it and try something different. Remember, the code you are looking for isthere; you just have to locate it.

 

Once you locate the desired code, study it,ignoring irrelevant elements. This is a skill you will have to learn. Manyexercises in this book will ask you to perform exactly this task. If you findit difficult to understand the code in its original context, copy it into atemporary file and remove all irrelevant parts. The formal name of thisprocedure is slicing (see Section 9.1.6), but you can get the idea by examininghow we have informally applied it in the book's annotated code examples.

 

1.1.3 Maintenance

In other cases code, rather than being anexemplar, may actually need fixing. If you thinkyou have found a bug in a large system, you need strategies(战略) and tactics(战术)to let you read the code at increasing(渐增的) levels of detail until you havefound the problem. The key concept in this case is to use tools. Use thedebugger, the compiler's warnings or symbolic code output, a system calltracer, your database's Structured Query Language (SQL)logging facility, packet dump tools, andWindows message spy programs to locate a bug's location. (Read more in Chapter10 about how tools will help your code reading.) Examine the code from theproblem manifestation(表现) to the problem source. Do not follow unrelated paths.Compile the program with debugging support and use the debugger's stack tracefacility, single stepping, and data and code breakpoints to narrow down yoursearch.

 

If the debugger is not cooperating (the debuggingof programs that run in the background such as daemons and Windows services,C++ template-based code, servlets, and multithreaded code is sometimesnotoriously(十分地) difficult), consider adding print statements in strategiclocations(战略位置) of the program's execution path. When examining Java codeconsider using AspectJ to insert into the program code elements that willexecute only under specific circumstances. If the problem has to do withoperating system interfaces, a system call tracingfacility will often guide you very near the problem.

1.1.4 Evolution

In most situations (more than 80% of your time bysome measurements) you will be reading code not to repair a fault but to add new functionality, modify its existing features, adapt itto new environments and requirements, or refactor it to enhance itsnonfunctional qualities. The key concept in these cases is to beselective in the extent of the code you are examining; in most situations youwill actually have to understand a very small percentage of the overallsystem's implementation. You can in practice modify a million-line system (suchas a typical kernel or window system) by selectively understanding and changingone or two files; the exhilarating feeling that follows the success of such anoperation is something I urge you to strive to experience. The strategy forselectively dealing with parts of a large system is outlined below.

Locate the code parts that interest you.

Understand the specific parts in isolation.

Infer the code excerpt's relationship with therest of the code.

 

When adding newfunctionality to a system your first task is to find the implementationof a similar feature to use as a template for the one you will be implementing.Similarly, when modifying an existing feature you first need to locate theunderlying code. To go from a feature's functional specification to the codeimplementation, follow the string messages, or search the code using keywords. Asan example, to locate the user authentication code of the ftp command you wouldsearch the code for the Password string:

Once you have located the feature, study itsimplementation (following any code parts you consider relevant), design the newfeature or addition, and locate its impact area-the other code parts that willinteract with your new code. In most cases, these are the only code parts youwill need to thoroughly understand.

 

Adapting code to new environments is a differenttask calling for another set of strategies. There are cases where the twoenvironments offer similar capabilities: you maybe porting code from Sun Solaris to GNU/Linux or from a Unix system toMicrosoft Windows. In these situations the compiler can be your most valuablefriend. Right from the beginning, assume you have finished the task and attemptto compile the system. Methodically modify the code as directed by compilationand linking errors until you end with a clean build cycle, then verify thesystem's functionality. You will find that this approach dramatically lessensthe amount of code you will need to read. You can follow a similar strategyafter you modify the interface of a function, class, template, or datastructure. In many cases, instead of manually locating your change's impact,you follow the compiler's error or warning messages to locate the troublespots. Fixes to those areas will often generate new errors; through thisprocess the compiler will uncover for you the code location influenced by yourcode.

When the code's new environment is completely different from the old one (for example, asis the case when you are porting a command-line tool to a graphical windowingenvironment) you will have to follow a different approach. Here your only hopefor minimizing your code-reading efforts is to focus at the point where theinterfaces between the old code and the new environment will differ. In theexample we outlined, this would mean concentrating on the user interaction codeand completely ignoring all the system's algorithmic aspects.

 

A completely different class(类别) of code evolution(演化)changes(变革) concerns(涉及到) refactoring(重构). These changes are becomingincreasingly(日益) important as some types of development efforts adopt extremeprogramming(极限编程) and agile programming(敏捷编程) methodologies(方法论). Refactoringinvolves a change to the system that leaves its static external behaviorunchanged but enhances some of its nonfunctional qualities, such as itssimplicity, flexibility, understandability, or performance. Refactoring has acommon attribute with cosmetic surgery. When refactoring you start with aworking system and you want to ensure that you will end up with a working one.A suite of pertinent(相干的) test cases will help you satisfy this obligation, soyou should start by writing them. One type of refactoring concerns fixing aknown trouble spot. Here you have to understand the old code part (which iswhat this book is about), design the new implementation, study its impact onthe code that interfaces with your code (in many cases the new code will be adrop-in replacement), and realize the change.

 

A different type of refactoring involves spendingsome "quality time" with your software system, actively looking forcode that can be improved. This is one of the few cases where you will need anoverall picture of the system's design and architecture; refactoringin-the-large is likely to deliver more benefits than refactoring in-the-small.Chapter 6 discusses ways to untangle large systems, while Chapter 9 outlines howto move from code to the system's architecture. When reading code to search forrefactoring opportunities, you can maximize your return on investment bystarting from the system's architecture and moving downward to look atincreasing levels of detail.

 

1.1.5 Reuse

You might also find yourself reading code to lookfor elements to reuse. The key concept(观念) hereis to limit your expectations(期望值). Codereusability(重用性) is a tempting(诱人的) but elusive concept; limit your expectations and you will not be disappointed.It is very hard to write reusable code. Over theyears comparatively little(相当少地) software hassurvived the test of time and been reused in multiple and different situations.Software parts will typically become reuse candidates after they have beengracefully extended and iteratively adapted to work on two or three differentsystems; this is seldom the case in ad-hoc developed software. In fact,according to the COCOMO II software cost model[BCH+95], crafting(vt.打造) reusable software can add(增加) as much as 50% to thedevelopment effort.

When looking for code to reuse in a specificproblem you are facing, first isolate the code that will solve your problem. A keyword-based search through the system's code willin most cases guide you to the implementation. If the code you want to reuse isintractable, difficult to understand and isolate, look at larger granularitypackages or different code. As an example, instead of fighting to understandthe intricate relation of a code piece with its surrounding elements, considerusing the whole library, component, process, or even system where the coderesides.

One other reuse activity involvesproactively examining code to mine reusable nuggets. Here(给) your best bet(n.观点、意见)is to look for code that is already reused, probably within the system you areexamining. Positive signs indicating reusable code include the use of asuitable packaging method (see Section 9.3) or a configuration mechanism.

 

1.1.6 Inspections(评审)

Finally, in some work settings, the task of codereading may be part of your job description. A number of software developmentmethodologies use technical reviews such as walkthroughs, inspections, round-robin(回归的) reviews, and other types of technicalassessments as an integral part of the development process. Moreover, whenpracticing pair programming while applying the extreme programming methodologyyou will often find yourself reading code as your partner writes it. Codereading under these circumstances requires a different level of understanding,appreciation, and alertness. Here you need to be thorough. Examine code to uncover errors in function and logic. Thevarious elements we have marked in the margin as dangerous (see the icon atleft) are some of the things you should be wary of. In addition, you should beready to discuss things you fail to see(vt.明白); verify that the code meets allits requirements.

 

Nonfunctional issues of the code should absorb anequal part of your attention. Does the code fit with your organization'sdevelopment standards and style guides? Is there an opportunity to refactor?Can a part be coded more readably or more efficiently? Cansome elements reuse an existing library or component? While reviewing asoftware system, keep in mind that it consists of more elements than executablestatements. Examine the file and directory structure, the build andconfiguration process, the user interface, and the system's documentation.

 

Software inspections and related activitiesinvolve a lot of human interaction(沟通). Use software reviews as a chance tolearn, teach, lend a hand, and receive assistance.

 

Chapter 2. Basic Programming Elements

bottom up adv.颠倒,干杯

2.1 A Complete Program

arsenal

When examining a program for the first time main can be a good starting point.

expedient adj.有利的

The argv array isterminated with a NULL element, allowing twodifferent ways to process arguments: either by counting based on argc or bygoing through(遍历) argv and comparing each value against NULL.

我一般都用第一种,其实第二种也挺好的。

 

Note the nonintuitive(不符合直觉的) return value ofstrcmp when it is used for comparing two strings for equality. When the stringscompare equal it returns 0, the C value of false. Forthis reason you will see that many C programs define a macro STREQ to return true when two strings compareequal, often optimizing the comparison by comparing the first twocharacters on the fly:[6]

#define STREQ(a, b) (*(a) == *(b)&& strcmp((a), (b)) == 0)

意思是说,strcmp函数一般只是被我们用来比较是否相等,按常理,相等应该返回真,不相等返回假,但事实并不是这样,而是相等返回0(假),不等返回1、-1(真)。所以才出现了上面的STREQ。Consider how the C compiler could optimize strcmp calls???

 

对于printf、putchar我们一般没有检查返回值,检查返回值的过程实在是让人感到乏味,但是这些函数又是非常容易失败的,Apractical(实用的) compromise(折衷) you may encounter is to check for errors on thestandard output stream before the program terminates.

例:

if (ferror(stdout))

    err(1,"stdout");

 

2.2 Functions and Global Variables

When examining a nontrivial program, it is usefulto first identify its major constituent(n.组成)parts. In our case, these are the global variables (Figure2.2:1) and the functions main

 

如果你打算一个变量或者函数只在某一个文件中使用,可以在前面加上static,这是我们经常忽略的。

例:

static   void    usage (void);

 

韩经理那个傻比,如果在一个.cpp中static int i=100;而在另一个文件中externint i;那么会出现链接错误,相当于extern那个i还没有定义呢。

To understand what a function (ormethod) is doing you can employ(使用) one of the following strategies.

1.Guess, based on the functionname.

2.Read the comment at thebeginning of the function.

3.Examine how the function isused.

4.Read the code in the functionbody.

5.Consult(参考) external programdocumentation

However, you should alwaysbe prepared to revise your initial guesses following new evidence that yourcode reading will inevitably unravel.

 

Based on this form of gradualunderstanding you can employ a strategy for understanding difficult codesimilar to the one often used to combine the pieces of a jigsaw puzzle: start with the easy parts.

 

2.3 while Loops, Conditions, and Blocks

Most development environments provide on-linedocumentation for library functions, classes, and methods.(例如,windows中的MSDN、UNIX中的man、Java中的JDK文档)

Make it a habit to read the documentation oflibrary elements you encounter; it will enhance both your code-reading andcode-writing skills.

 

2.4 switch Statements

case 'a':

   fts_options |= FTS-SEEDOT;

    /* FALLTHROUGH */         如果这儿没有break的话,应该加上注释。(和华为编程规范一致)

case 'A':

   f_listdot = 1;

    break;

 

Even when one knows that only a fixed set ofvalues will be processed by a switch statement, it is good defensiveprogramming practice to include a default label. Such a default label can catchprogramming errors that yield unexpected values and alert the programmaintainer, as in the following example.[18]

 

    switch(program) {

    caseATQ:

[...]

    caseBATCH:

       writefile(time(NULL), 'b');

       break;

    default:           //无论如何都加default分支

       panic("Internal error");  //可以在这儿打印错误提示信息(和华为编程规范一致)

       break;

    }

 

2.5 for Loops

heuristics adj.启发式的

Code reading involves many alternative strategies:bottom-up(从下往上)and top-downexamination, the use of heuristics(n.拭探法, 直观推断),and review of comments and external documentationshould all be tried as the problem dictates.

 

for (i = 0; i < len; i++) {    //这是我们的标准循环,表示循环len次

On the other hand, any deviation from this style,such as an initial value other than 0 or a comparison operator other than <,should alert you to carefully reason about theloop's behavior.

for (i = 0; i <= extrknt; i++)    //extrknt+1次

for (i = 1; i < month; i++)       //month-1次

可以归结为:1减 等加

 

2.6 break and continue Statements

 

2.7 Character and Boolean Expressions

cryptic adj.神秘的

daunting adj.使人畏缩的

disentangle vt.解开

Many expressions are writtenbased on this short-circuit evaluation property andshould be read in the same way. When reading a conjunction, you can alwaysassume that the expressions on the left of the expression you are examining aretrue; when reading a disjunction, you can similarly assume that the expressionson the left of the expression you are examining are false.

 

2.8 goto Statements

 

Chapter 4. C Data Structures

有时间再慢慢看!

 

Chapter 6. Tackling LargeProjects

 

 

Chapter 8. Documentation

 

Chapter 9. Architecture

 

Chapter 10. Code-Reading Tools

 

 

Colophon n.书籍的末页

 

Appendix E. Maxims(n.行为准则的简洁形式) for Reading Code

 

Chapter 1: Introduction

 

1.Make it a habit to spend timereading high-quality code that others have written. (p. 3)

 

2.Read code selectively and witha goal in your mind. Are you trying to learn new patterns, a coding style, away to satisfy some requirements? (p. 4)

 

3.Notice and appreciate thecode's particular nonfunctional requirements that might give rise to a specificimplementation style. (p. 4)

 

4.When working on existing code,coordinate your efforts with the authors or maintainers to avoid duplication ofwork or bad feelings. (p. 5)

 

5.Consider the benefits youreceive from open-source software to be a loan; look for ways to repay it bycontributing back to the open-source community. (p. 5)

 

6.In many cases if you want toknow "how'd they do that?" there's no better way than reading thecode. (p. 5)

 

7.When looking for a bug, examinethe code from the problem manifestation to the problem source. Avoid followingunrelated paths. (p. 6)

 

8.Use the debugger, thecompiler's warnings or symbolic code output, a system call tracer, yourdatabase's SQL logging facility, packet dump tools, and windows message spyprograms to locate a bug's location. (p. 6)

 

9.You can successfully modifylarge well-structured systems with only a minimal understanding of theircomplete functionality. (p. 7)

 

10.When adding new functionalityto a system, your first task is to find the implementation of a similar featureto use as a template for the one you will be implementing. (p. 7)

 

11.To go from a feature'sfunctional specification to the code implementation, follow the string messagesor search the code using keywords. (p. 7)

 

12.When porting code or modifyinginterfaces, you can save code-reading effort by directing your attention to theproblem areas identified by the compiler. (p. 8)

 

13.When refactoring, you startwith a working system and want to ensure that you will end up with a workingone. A suite of pertinent test cases will help you satisfy this obligation. (p.8)

 

14.When reading code to searchfor refactoring opportunities, you can maximize your return on investment bystarting from the system's architecture and moving downward, looking atincreasing levels of detail. (p. 9)

 

15.Code reusability is a temptingbut elusive concept; limit your expectations and you will not be disappointed.(p. 9)

 

16.If the code you want to reuseis intractable and difficult to understand and isolate, look at largergranularity packages or different code. (p. 9)

 

17.While reviewing a softwaresystem, keep in mind that it consists of more elements than executablestatements. Examine the file and directory structure, the build andconfiguration process, the user interface, and the system's documentation. (p.10)

 

18.Use software reviews as achance to learn, teach, lend a hand, and receive assistance. (p. 10)

 

 

Chapter 2: Basic ProgrammingElements

未完

 

Chapter 6: Tackling(接受(比如一名对手或一个问题)的挑战) Large Projects

116.You can examine a project'sorganization by browsing its source code tree-the hierarchical directory structure containing the project's sourcecode. The source code tree often reflects the project's architectural andsoftware process structure. (p. 181)

 

117.Often the source code tree ofan application mirrors(vt.反映) the application's deployment structure. (p. 181)

 

118.Do not let huge source codecollections daunt(使沮丧) you; typically these arebetter organized than smaller. (p. 186)

 

119.When you work on a largeproject for the first time, spend some time acquainting(熟悉) yourself with itsdirectory tree structure.

 

120.A project's "sourcecode" encompasses(包含) a lot more than the computer language instructionscompiled to obtain an executable program; a project's source code treetypically also includes specifications(说明书), end-user and developerdocumentation, test scripts, multimedia resources, build tools, examples,localization files, revision history, installation procedures, and licensinginformation. (p. 189)

 

121.The build process of largeprojects is typically specified declaratively by means of dependencies.Dependencies are translated into concrete build actions by tools such as makeand its derivatives. (p. 191)

 

122.In large projects makefilesare often dynamically generated after a configuration step; you will need toperform the project-specific configuration before examining the makefile.

 

123.To inspect the steps of alarge build process, you can dry-run make by using the -n switch.

 

124.A revision control systemprovides a way to obtain an up-to-date version of the source code from itsrepository. (p. 204)

 

125.Use commands that displayexecutable file revision identification keywords to match an executable withits source code. (p. 207)

 

126.Use bug-tracking code numbersthat appear in revision logs to locate an issue description in the bug-trackingdatabase. (p. 209)

 

127.Use the revision controlsystem version repository to identify how particular changes were implemented.(p. 209)

 

128.Many different aspects of thesoftware development process, including configuration, build processmanagement, code generation, testing, and documentation use custom-built tools.

 

129.Use a program'sdebugging output to help you understand crucialparts of a program's control flow and data elements. (p. 216)

 

130.The places where atracing statement is located typically mark importantparts of an algorithm function. (p. 216)

 

131.Assertions are used to verify steps in the operation of an algorithm, parametersreceived by a function, a program's flow of control, properties of theunderlying hardware, and the results of test cases. (p. 218)

 

132.Usealgorithm verification assertions to confirm(证实) your understanding of analgorithm's operation or as a point to start your reasoning. (p. 218)

 

133.Often function argument andresult assertions document a function's preconditions and postconditions. (p.219)

 

134.Use assertions that testcomplete functions as specification statements for each given function. (p.220)

 

135.Test cases(测试用例) can be apartial substitute for functional specifications(功能说明书).

 

136.Use test case input data to dry-run(演习) source code sequences. (p. 223)

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值