i is not visible outside the module; j is globally accessible.
That is, another module, which is linked to it, can do
extern int j;
and then be able to read and write the value in j. The same other module cannot access i, but could declare its own instance of it, even a global one—which is not visible to the first module.
The difference is that i has internal linkage, and j has external linkage. This means you can access j from other files that you link with, whereas i is only available in the file where it is declared.
Scope of static variable/function is within the same file despite you include the file as part of a different source file.
Scope of global variable is throughout the files in which it is included. To include the variable in a different source file, we use extern before the variable declaration. No memory is allocated again for the variable in this case.
extern is used to declare a C variable without defining it. extern keyword extends the visibility of the C variables and C functions. Since functions are visible through out the program by default, the use of extern is not needed in function declaration/definition. Its use is redundant.