=========================================================================
These are the correct answers (for questions which *have* a correct
answer, of course). My comments are the sentences in full capitals
between square brackets, [LIKE THIS].
=========================================================================

What are `CVS' and `SVN'?
[ ] Programming languages
[ ] Text editors
[X] Revision control systems
[ ] Licenses
[ ] Operating systems
[ ] Compilers
[ ] Online chat systems
[ ] Old computers

Think you are logged in at a typical GNU/Linux (or other Unix-like)
system, and you have a text file README in your home directory,
containing only the text "toto", with no final newline.
What's the output of the sh command
  sort ~/README | grep foo
?
[X] The output is empty
[ ] A 'broken pipe' error message
[ ] toto
[ ] foo

On the same system, what's the output of
  for i in `seq 1 100`; do echo $i; done
?
[X] The sequence of natural numbers from 1 to 100, one per line
[ ] The sequence of natural numbers from 1 to 100, all on the same line
[ ] One hundred lines containing the text "$i"
[ ] An error message
[BY DEFAULT `echo' PRINTS ITS ARGUMENTS *FOLLOWED BY A NEWLINE*. ON GNU
 SYSTEMS YOU CAN ASK `echo' NOT TO PRINT THE NEWLINE BY PASSING THE '-n'
 OPTION, BUT THIS WAS NOT DONE IN THE COMMAND LINE ABOVE.]

On the same system, what's the output of
  for i in `seq 1 100`; do $i; done
? (there is no "echo" this time)
[ ] One error message
[X] One hundred error messages
[BY DEFAULT AN ERROR IN A SEQUENCE OF COMMANDS, OR LOOP, DOES *NOT* CAUSE
 THE SEQUENCE OR LOOP TO BE ABORTED.]

On the same system, what's the output of
  X=10; echo $(( $X + $X ))
?
[ ] "$(( 10 + 10 ))"
[ ] "$(( $X + $X ))"
[X] "20"
[ ] An error message
[YES, YOU CAN DO ARITHMETICS ON THE UNIX SHELL. AND YOU CAN USE VARIABLES,
 LOOPS, FUNCTIONS, AND ARRAYS.
 EVEN IF NOT VERY BEAUTIFUL, THE SHELL IS A COMPLETE PROGRAMMING LANGUAGE.]

On my system
  ls -l
gives the output
  total 8
  -r-x------ 1 luca luca 7431 Nov  6 23:14 not-readable
What's the meaning of "-r-x------"?
[ ] It's the file name
[X] It's a description of file permissions
[ ] It's the beginning of the file contents
[ ] It's the file license

gets() is a C library function,
   taking a single parameter P of type char*; it copies an
   arbitrarily long string written on the terminal by the
   user into memory, starting at the address P.
Why is it a *bad* idea to use gets()?
[ ] It has exponential time complexity in the worst case
[ ] It has exponential space complexity in the worst case
[ ] It's encumbered by a software patent
[X] It causes buffer overflows
[ ] scanf() is easier to use and does the same job
[ ] It's non-standard
[`gets()' TAKES A POINTER P AS ITS ONLY ARGUMENT: THE BUFFER POINTED
 BY P MUST BE ALREADY ALLOCATED BY THE CALLER.
 EVEN IF THE BUFFER IS MADE VERY LARGE, THE USER CAN ALWAYS OVERFLOW
 IT, BY ENTERING AN EVEN LARGER STRING.
 ALTHOUGH FOR THIS REASON ITS DESIGN IS COMPLETELY WRONG, `gets()'
 *IS* STANDARD: IT'S INCLUDED IN ISO C.
 *DON'T* USE `gets()', EXCEPT FOR DOING QUICK TESTS IN NON-RELEASED
 CODE.]

The following snippet of C code is compiled by a typical compiler
into machine code running on typical (modern) hardware:
  #define N 20000
  char a[N][N];

  void f(void){
    int i, j;
    for(i = 0; i < N; i++)
      for(j = 0; j < N; j++)
        a[i][j] = 'x';
  }

  void g(void){
    int i, j;
    for(i = 0; i < N; i++)
      for(j = 0; j < N; j++)
        a[j][i] = 'x';
  }
Do you think that f() and g() have very different running times?
[X] Yes, one of the functions is much faster than the other one
[ ] No, they take the same time to complete or there is only a
    very small difference
Why?
[THERE IS A *DRAMATIC* DIFFERENCE ON ALL MODERN MACHINES, DUE TO
 THE DIFFERENT MEMORY ACCESS PATTERNS IN f() AND g(): ONE
 FUNCTION FILLS THE MATRIX ROW BY ROW, AND THE OTHER ONE COLUMN
 BY COLUMN. ACCESSING A LARGE ARRAY *SEQUENTIALLY* IS MUCH FASTER
 THAN IN RANDOM ORDER: ON MY MACHINE I SEE A DIFFERENCE OF ABOUT
 1000%.
 THE REASON IS SIMPLY THAT *CACHE*, PRESENT IN ALL MODERN MACHINES,
 REQUIRES *MEMORY ACCESS LOCALITY* TO WORK IN AN EFFECTIVE WAY.
 ESTIMATING THE COMPLEXITY OF REAL CODE IS *HARD* AND REQUIRES
 EXPERIENCE, BUT SOMETIMES YOU NEED TO DO IT, ESPECIALLY WHEN
 PROGRAMMING WITH RELATIVELY LOW-LEVEL LANGUAGES LIKE C (YOU
 TYPICALLY USE C FOR GETTING GOOD PERFORMANCE...).]

Linux (Linux is the *kernel*, not the whole operating system) is
written in C. How long do you think its source code is? Try to
make a realistic estimation.
[ ] between 1,000      and 10,000      lines
[ ] between 10,000     and 100,000     lines
[ ] between 100,000    and 1,000,000   lines
[X] between 1,000,000  and 10,000,000  lines
[ ] between 10,000,000 and 100,000,000 lines

GCC is also written in C. How long do you think its source code is?
Try to make a realistic estimation.
[ ] between 1,000      and 10,000      lines
[ ] between 10,000     and 100,000     lines
[ ] between 100,000    and 1,000,000   lines
[X] between 1,000,000  and 10,000,000  lines
[ ] between 10,000,000 and 100,000,000 lines
[GCC IS MILLIONS OF LINES LONG. NOTE THIS DOES *NOT* INCLUDE THE C
 LIBRARY.]
