Observer to review my C Interview response

Thread Starter

Kittu20

Joined Oct 12, 2022
511
Hey Experts,

I am looking for a mentor or observer to help me understand why I am not succeeding in my interviews. I have recently attended several interviews for Embedded C Developer position but, unfortunately, I am failing in C concepts. I believe that my C knowledge is sound, but I suspect that there might be an issue with how I present my answers or communicate my thoughts during the interviews even though my understanding seems correct.

I would like to discuss some of the questions and answers that I’ve given during these interviews and get your feedback on how I can improve my performance.

For example:

Interviewer’s Question: Can you describe how a C compiler translates source code into executable files? What are the steps involved in this process?

My Answer:

My understanding is that the process of translating source code into machine code or executable files depend on the specific compiler being used , but generally, it involves into four steps.

Preprocessor: This is the first step, where the preprocessor takes the source file and performs several operations such as It includes the contents of header files into the source file, replaces defined names with their values in the code, perform conditional operations, removes comments etc. and produce a preprocessed source file.

Compiler: Then compiler takes the preprocessed source code and converts it into assembly code. It ensure the syntax and semantics are correct before generating the assembly code. and produce a assembly file.

Assembler: The assembler then converts the assembly code into machine code (object code) and produce object file.

Linker: The linker combines multiple object files generated by the assembler and produce final executable file. It resolves references between functions or variables located in different object files and ensures that all are correctly linked

I believe that having a mentor or observer ( @WBahn @Papabravo ) would help me identify any gaps in my responses or areas where my communication may be lacking.

Note: I posted this thread in the Programming forum, but it is showing in the Job and Career Advice forum. I believe this topic is more suitable for the Programming forum
 
Last edited:

MrChips

Joined Oct 2, 2009
34,628
In my opinion, I believe that the interviewer is also testing your communication skiils. I believe that the interviewer is not looking for exact correct answers.

There is always a danger of saying too much, saying more than is necessary.
Don’t try to impress your interviewer with how smart you are. Don’t put your interviewer to sleep with long boring answers.

My answer would be:

The compiler converts programming instructions into assembler code. The assembler converts the assembler code to machine code.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
There is always a danger of saying too much, saying more than is necessary.
Don’t try to impress your interviewer with how smart you are. Don’t put your interviewer to sleep with long boring answers.
I appreciate your focus on communication skills during interviews. However, I have a slightly different opinion. I think it’s also important to show a strong understanding of the technical aspects.

Sorry but I believe my answer is well-balanced—not too short and not too long. Even though I didn’t include examples for each step, I tried to explain the key processes clearly and simply. This way, I keep the conversation focused without complicating it for the interviewer.
 

MrChips

Joined Oct 2, 2009
34,628
Put yourself in the shoes of the interviewer. The interviewer has a job to be done that day. They don’t really enjoy doing job interviews. They probably have ten or more interviews to conduct that day and they have to listen to the same boring answers. The sooner they can complete the interview, the better for them.

They are looking for a team player, not a techno wizard.
 

Ian0

Joined Aug 7, 2020
13,097
Was it an oral interview or written? If it was oral, did you deliver the answers as clearly as you wrote them? Without ums and ahs and y'knows? And did the interviewer looks like he was interested in your full and complete answer or were his eyes glazing over? Or weren't you observing his reactions?
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
Was it an oral interview or written? If it was oral, did you deliver the answers as clearly as you wrote them? Without ums and ahs and y'knows? And did the interviewer looks like he was interested in your full and complete answer or were his eyes glazing over? Or weren't you observing his reactions?
The interview was oral on Microsoft teams , which allowed for real-time interaction and discussion. He asked next question

Interviewer:
You mentioned that the preprocessor includes the content of header files. I’m going to give you a main.c file and a custom header file.

Can you explain to me what the content of main.c would look like after the preprocessor includes the header file?

my_header.h
C:
#ifndef MY_HEADER_H
#define MY_HEADER_H

// Structure Declaration
struct Person {
    char name[50];
    int age;
};

// Enumeration Declaration
enum Weekday {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
};

// Function Declarations
void greet(const char* name);
int getMax(int a, int b);

#endif // MY_HEADER_H
main.c
C:
#include <stdio.h>
#include "my_header.h"

// Macro Definitions
#define PI 3.14159
#define SQUARE(x) ((x) * (x))

// Function Implementations
void greet(const char* name) {
    printf("Hello, %s!\n", name);
}

int getMax(int a, int b) {
    return (a > b) ? a : b;
}

int main() {
    // Using the macros PI and SQUARE in a calculation
    float area = PI * SQUARE(5);
    printf("The area of a circle with radius 5 is: %.2f\n", area);

    // Using the structure
    struct Person person1;
    person1.age = 30;
    snprintf(person1.name, sizeof(person1.name), "John Doe");
    printf("Person: %s, Age: %d\n", person1.name, person1.age);

    // Using the enum
    enum Weekday today = MONDAY;
    printf("Today is day number %d of the week.\n", today);

    // Calling external functions
    greet("Alice");
    int maxVal = getMax(10, 20);
    printf("The maximum value is: %d\n", maxVal);

    return 0;
}
My Answer :
So the main.c would look like this after the pre-processor: I explained as written in comments but preprocessor remove comments

C:
#include <stdio.h>  // Standard library header included as-is

// Content of "my_header.h" is inserted here during preprocessing

// Structure Declaration
struct Person {
    char name[50];
    int age;
};

// Enumeration Declaration
enum Weekday {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
};

// Function Declarations
void greet(const char* name);
int getMax(int a, int b);

// Macro Definitions
#define PI 3.14159            
#define SQUARE(x) ((x) * (x))

// Function Implementations
void greet(const char* name) {
    printf("Hello, %s!\n", name);  // Normal function implementation, unchanged by preprocessing
}

int getMax(int a, int b) {
    return (a > b) ? a : b;  // Normal function implementation, unchanged by preprocessing
}

int main() {

    float area = 3.14159 * ((5) * (5));  // After macro expansion: PI is replaced with 3.14159, and SQUARE(5) becomes ((5) * (5))

    printf("The area of a circle with radius 5 is: %.2f\n", area);  // This line remains the same

    // Using the structure
    struct Person person1;  // Normal struct usage, no change by preprocessing
    person1.age = 30;
    snprintf(person1.name, sizeof(person1.name), "John Doe");  // Normal function call, unchanged
    printf("Person: %s, Age: %d\n", person1.name, person1.age);  // Normal printf usage, no change

    // Using the enum
    enum Weekday today = MONDAY;  // Enum usage, no change by preprocessing
    printf("Today is day number %d of the week.\n", today);  // No change

    // Calling external functions
    greet("Alice");  // Function call, unchanged
    int maxVal = getMax(10, 20);  // Function call, unchanged
    printf("The maximum value is: %d\n", maxVal);  // No change

    return 0;
}
Note : I want to clarify that while the exact content of the header file (my_header.h) and source file (main.c) may vary slightly, but purpose is same
 

WBahn

Joined Mar 31, 2012
32,706
The question about what it would look like after the preprocessor runs is a bit of a trick question. Many people would, somewhat naturally, assume that they were just being asked to deal with the #include of my_header.h. You, at least, expanded the macros where they were used. But you also left the macro #define statement in place, which the preprocess will remove them. As you noted, the preprocess will remove all comments, so that fact that you left in the comments -- and added more -- shouldn't have been a big issue.

You also missed out on an opportunity to point out some common "best practices" points, which they may or may not have been looking for. For instance, the header file included the actual definition of the structure, but that gives the programmer access to its members directly, as was done in the main() function in the example, meaning that the developer of the my_header.c file is stuck with that definition because if they change it, they will almost certainly break a bunch of code. To avoid this, it is common practice to only include the typedef for the structure and keep the actual definition in the my_header source code file and then provide prototypes for functions that access the members in the header file. This approach is not without downsides (nearly everything in engineering is a compromise) and often results in lower performance in exchange for the increased maintainability, so it may or may not be the appropriate route to take for a given application.
 

WBahn

Joined Mar 31, 2012
32,706
Hey Experts,

I am looking for a mentor or observer to help me understand why I am not succeeding in my interviews. I have recently attended several interviews for Embedded C Developer position but, unfortunately, I am failing in C concepts. I believe that my C knowledge is sound, but I suspect that there might be an issue with how I present my answers or communicate my thoughts during the interviews even though my understanding seems correct.

I would like to discuss some of the questions and answers that I’ve given during these interviews and get your feedback on how I can improve my performance.

For example:

Interviewer’s Question: Can you describe how a C compiler translates source code into executable files? What are the steps involved in this process?

My Answer:

My understanding is that the process of translating source code into machine code or executable files depend on the specific compiler being used , but generally, it involves into four steps.

Preprocessor: This is the first step, where the preprocessor takes the source file and performs several operations such as It includes the contents of header files into the source file, replaces defined names with their values in the code, perform conditional operations, removes comments etc. and produce a preprocessed source file.

Compiler: Then compiler takes the preprocessed source code and converts it into assembly code. It ensure the syntax and semantics are correct before generating the assembly code. and produce a assembly file.

Assembler: The assembler then converts the assembly code into machine code (object code) and produce object file.

Linker: The linker combines multiple object files generated by the assembler and produce final executable file. It resolves references between functions or variables located in different object files and ensures that all are correctly linked

I believe that having a mentor or observer ( @WBahn @Papabravo ) would help me identify any gaps in my responses or areas where my communication may be lacking.

Note: I posted this thread in the Programming forum, but it is showing in the Job and Career Advice forum. I believe this topic is more suitable for the Programming forum
The problem I have with this response is that most of it is largely proforma in that you could almost write it without knowing anything about what is actually happening. It comes across as being an exercise in memorization and regurgitation. Having said that, the question itself is so general that it is going to be a bit difficult that give an answer that does not have this flavor to it. It's good that you pointed out that the details depend on the specific compiler, though again that is pretty proforma. It probably would have been worth noting that the compiler generally performs some level of code optimization, either for speed or space. Also that the compiler is going to generate assembly instructions for a specific target platform, which might not be the platform that the compiler is running on (i.e., cross-platform compilation).

One thing that caught my eye is that you say that the compiler is going to ensure that the syntax and semantics are correct. How is it going to ensure that the semantics are correct? This response raises red flags about do you understand what the difference between syntax and semantics is, which again will make the interviewer wonder whether you understand the answer you are giving, or if you are just regurgitating something you found somewhere.

How much detail you should go into is always an unknown. If the interview is live, then interact with the interviewer. It's okay to say something like, "I'm not sure how much detail you want, so let me give you a failry high-level answer and, if you would like me to expand on any part of it, just let me know."
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
The problem I have with this response is that most of it is largely proforma in that you could almost write it without knowing anything about what is actually happening
I want to get your opinion on how to handle general interview questions. I was asked in many interview to "describe the memory layout of a C program".

Here’s the answer I give:

The memory layout of a C program depends on the specific hardware architecture, operating system, and compiler being used.

I can explain a general overview:

The memory layout of a C program is generally divided into four sections, each serving a specific purpose.

1) Text Section: This section stores the program’s instructions.

2) Data Section: This section is divided into two sections :

Initialized Data: This stores initialized variables, such as global and static variables with specific values.

BSS: This stores uninitialized variables, such as global and static variables.

3) Stack: This section stores local variables, function parameters etc.

4) Heap: Used for dynamic memory allocation.

I felt the answer was clear, but I want to know if I could have improved my approach. Should I keep answers like this high-level or provide more details in a general question? Also, how should I prepare for follow-up questions if they ask me to elaborate on a specific section? Any advice would be great.

@WBahn
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
What is software that takes source code as input and creates tokenized output in an interpretative language?
Thanks for your input, but I’m not sure how your question relates to my topic about memory layout. I was looking advice on the answer I gave for an interview question about the memory layout of a C program, where I explained it in terms of text, data, stack, and heap sections.

Could we get back to discussing that?
 

djsfantasi

Joined Apr 11, 2010
9,237
Well, in that case the software may also be referred to as a compiler. But your definition excludes this case. I would not state that a compiler produces assembly language (specifically) but rather a machine readable form of the program.
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
Well, in that case the software may also be referred to as a compiler. But your definition excludes this case. I would not state that a compiler produces assembly language (specifically) but rather a machine readable form of the program.
I agree that my description was somewhat limited by stating that the compiler specifically produces assembly language. As you pointed out, the main goal of the compiler is to produce machine-readable code, and the form it takes (whether assembly, machine code, or otherwise) can vary depending on the system and compiler design.

If you don't mind, I’d like to ask for your advice on how you would approach answering a question like this in an interview . How would you balance providing enough detail while keeping the explanation clear and concise, especially when discussing general question not specific question ?
 
Last edited:

Thread Starter

Kittu20

Joined Oct 12, 2022
511
That particular part of the process is generally referred to as a parser, or a tokenizer. It is one stage in the typical compilation process.
This question about C memory layout come up in many interviews. Based on your experience, how should I approach tackling this type of question? Do you think my current response is relevant, or is there a better way to present it more effectively?
 

djsfantasi

Joined Apr 11, 2010
9,237
I’m way past my interviewing stage so my skills are rough. But I’d approach it like this:

“A compiler takes source code from the appropriate supported language and converts it into machine readable code. It may also perform pre-processing.

“A linker resolves all external references, such as existing libraries or other compiler code. It outputs an executable.”
 

Thread Starter

Kittu20

Joined Oct 12, 2022
511
I’ve been asked in interviews: "Can you describe the storage classes and their types in C?"

Here’s the answer I give:

In C language, storage classes define the scope and lifetime of variables.

There are four primary storage classes in C:

Auto (Default): If we don't specify a storage class, the default is auto, which applies to local variables. These variables have a local scope (only accessible within the function or block) and a limited lifetime (created and destroyed within the block or function).

Extern: Used to declare a global variable that is defined in another file. This allows the variable to be shared across different files in a program. Without extern, we can't access a variable defined in another file.

Static (Global and Local):

Global static variables: it define scope and accessible only within the file where it's declared. Other files cannot access them, even if we try to use extern. It can be indirectly modify using pointer only

Local static variables: it define lifetime of variables. Even though they are local to the function, their value is retained between function calls. Unlike regular local variables (which are re-initialized every time the function is called), static local variables preserve their value across multiple invocations.

Register: register suggests storing the variable in a CPU register. However, the compiler may decide whether to do this or not.

Should I add or modify anything to improve it?
 

BobTPH

Joined Jun 5, 2013
11,463
I agree completely with @WBahn, your answers sound like a recitation from memory and do not demonstrate an understanding of the subject. Much like all the Latin I had to recite as an alter boy (for non-catholics, a boy child who assists the priest in the ritual of the catholic mass). I could recite the Latin but I could not have told you what each word meant.
 

BobTPH

Joined Jun 5, 2013
11,463
I agree completely with @WBahn, your answers sound like a recitation from memory and do not demonstrate an understanding of the subject. Much like all the Latin I had to recite as an alter boy (for non-catholics, a boy child who assists the priest in the ritual of the catholic mass). I could recite the Latin but I could not have told you what each word meant.
What I would recommend is a less detailed, more chatty style of answer. You want to allow the interviewer the opportunity to ask followup questions to probe your understanding. If you say everything you know up front, she cannot do that, or you will get questions that you cannot answer.

For the first question, something like:

“First you run the .c files through a compiler. It creates object files that have the code translated to machine language. then you take those object files, and some libraries, and give them to the linker. It combines them into an executable file.”

You might get a follow up like:

“What about preprocessing?”

You might answer:

“Oh, yeah. The .h files have to be included and macros have to be expanded. That could be done in the first pass of a compiler, or maybe as a separate program run before the complier.”

The interviewer is looking for is a discussion, not a lecture.
 
Last edited:

Thread Starter

Kittu20

Joined Oct 12, 2022
511
I agree completely with @WBahn, your answers sound like a recitation from memory and do not demonstrate an understanding of the subject. Much like all the Latin I had to recite as an alter boy (for non-catholics, a boy child who assists the priest in the ritual of the catholic mass). I could recite the Latin but I could not have told you what each word meant.
Based on your comments, I've refined my explanation. I believe this enhances the clarity and relevance of the information.

In C, storage classes define the scope and lifetime of variables.

There are four main types:

Auto: This is the default storage class for local variables. If we don’t specify a storage class, a variable is considered auto. These variables are accessible only within the function or block they're declared in, and they exist only during that function's execution. We use auto for temporary local variables.

Extern: This class is used to declare a global variable defined in another file. It allows us to share variables across multiple source files. We use extern when we need access to global variables defined elsewhere in our program.

Static: There are two types here:

Global Static: This restricts the variable's scope to the file where it's declared, preventing access from other files. We use it when we want to limit the variable's visibility.

Local Static: This retains its value across multiple function calls, keeping its state even after the function exits. We use it when we need a variable to maintain its value between function calls.

Register: This suggests storing the variable in a CPU register for faster access.

If you @BobTPH have any further suggestions that could improve my understanding, I would like to hear them.
 
Top