Software Engineering

Written Test #1 on Code Complete

 

1.____ (T. for F.)   Debugging aids should be incorporated into early stage of coding . For C++, you can use the compiler preprocessor features such as #if defined( ) to conveniently control the levels of debugging aid used or to completely remove the debug aid when trying to produce optimized executables.

 

2. ____ (T. for F.) In general, a high-quality module should exhibit strong coupling and loose cohesion.

 

3. ____ (T. for F.)  In using psuedo-code programming, we should carefully document the preconditions and postconditions of a routine. However, in defensive programming, we don’t want to assert these preconditions and postconditions in the routine since this always significantly slows down the execution severely.

 

4. ____ (T. for F.)  Testing can be conducted side by side with the code development and or after the coding. But it is not very useful to have test cases even before starting the coding since it doesn’t help the requirement analysis, specification, or coding.

 

5. ____ (T. for F.) In general, a high-quality module should be constructed in a way that the user can use it without much knowledge of complex data structures or the logic used in the implementation inside the module.

 

6. ____ (T. for F.)  Most of the time in the industry, developers can exhaustively test all possible inputs to a routine or a program to verify whether the implementation is correct in all possible cases.

 

7.____ (T. for F.)  Both collaborative development of code (such as code review and inspection between peer programmers) and testing of code can help find faults and errors hidden in the code. However testing is far more economic in cost and far more effective in finding most errors.

 

8. ____ (T. for F.)  Structured basis testing assures that each statement of the code is executed at least once in some of the test cases. For a code segment such as 

 if (x>1  | |  y<1)  z--;                          

we need a case that will run through the segment with  (x>1 ) being true, a case that will run through the segment with  y<1 ) being true, and a case that will run through the segment with  (x>1  | |  y<1) being false.

 

9. ____ (T. for F.)  For data-flow testing, we are concerned with the states of data and the program executions under different trajectory of changing data states. For a single variable, it typically goes from Defined to Used for a while and then may be Killed in the end.  Going from Killed  to Used  or from Killed to Killed again implies serious misuse of the data in the code. 

 

10. ____ (T. for F.)  Structured basis testing already assures all statements about the definitions of data (i.e. declaration and initialization of variables) are executed at least once by some test cases. In data-flow testing, we want to have test cases running through all the possible Defined-Used combinations of data (key variables).

 

11. ____ (T. for F.)  When using variables, long spans between references to a particular variable is a good programming practice that can reinforce the programmer’s understanding of the role of the variable in the program.

 

12. ____ (T. for F.) It is a good practice to keep the declaration of variables and the usage of them close together and to initialize the values of variables when they are declared.

 

13. As his program evolves, Larry needs to enhance the code of a routine A and then the code of another routine B. It turns out that A and B have a lot of common functionality, and thus Larry decides to copy a big chunk of existing code in A into B to provide the functionality in B. Is this a good way to structure the code? Why or why not? If it is not good, what would you do alternatively?

 

 

14. Briefly explain your understandings of cohesion and coupling in the context of the construction and composition of routines, packages, and modules.

 

 

15. Consider the following C++  function:

bool func(int x, int y)  { if ( x>0 && x/y > 1) return 1;   else  return 0; }

What do you think should be the preconditions of this function? Could the function trust all the input data without checking? Why or why not?  If not, apply defensive programming here to avoid potential problems.

 

 

16. Consider the situation when using C++: (i) you are implementing a linked list class for storing information in linked-list objects and (ii) you want to provide a copy constructor for copying the contents of a linked-list object to initialize the contents of a newly created linked-list object. You can use the default shallow copy of C++ or implement deep copy into your copy constructor. What is the difference between these two options? Which one do you prefer? Why?