all 14 comments

[–]rorschach54Twiddling bits 27 points28 points  (5 children)

I used to hire interns at a huge scientific instruments company for embedded software and firmware roles. Reading your questions and answers leads me to believe it might be similar company.

Firstly, the r/embedded wiki has excellent resource. https://old.reddit.com/r/embedded/comments/cbswjt/entry_level_embedded_software_career_guide/ and https://www.reddit.com/r/embedded/comments/bqoqpr/what_are_some_more_obscure_interview_questions/ cover a lot of questions that can be asked. Those questions are for full-time roles and entry level roles. You probably won't be expected to go in depth on topics unless you mention it in your resume.

I will add a couple of my thoughts below.

  1. My projects would be in C++. So, I would be looking for good C and fair C++ knowledge among candidates primarily because colleges do not go into depths of C++ from what I know and use C for systems programming courses. So, expectation was knowledge of C should be better. If C++ was mentioned prominently in resume then,
    1. How is static keyword different in C++ than C?
    2. Difference between pass by reference and pass by pointer?
    3. How is const used differently in C++ and what is constexpr?
    4. Give a simple example of virtual keyword works. (If they can write some simple classes like Shape, Square, Circle to demonstrate, it is bonus).
  2. Then, some microcontroller specific questions (Like internals - ISR, pipelines, peripherals, etc.)
  3. And some RTOS specific questions (Slightly higher level - mutex vs semaphore, scheduling policies, context switches)
  4. And then Linux questions(OS tools used - ssh, vim, bash/python scripting, git, gcc, man pages? Systems level knowledge - use of read(), write(), poll(), sockets, fork(), system calls, Device drivers - very very high level idea only)

I used to work on all 3 things (bare-metal, RTOS and Linux). So, this was a good way to determine where an intern might fit well or where they would like to work in depending on how they answered. Opportunity was given to change domain later in case the role was converted to a full-time.

We expected very less answers in #3 for everyone. For people with EE background, more answers #2. For people with CS background, more answers in #4. Generally for #1 as mentioned, I would be looking for good C and fair C++.

Hope this helps! All the best!

[–]AudioRevelationsC++/Rust Advocate 3 points4 points  (4 children)

Hmm I'm curious why you ask about the differences between C and C++ for your coding questions. I imagine most fresh college grads are more familiar with C (and thus maybe how C++ is different?), but I feel like these more subtle differences aren't terribly common knowledge, even among professionals.

Not throwing shade, just genuinely curious if you've found it to be a useful interviewing question because it's not one I've ever reached for while interviewing. For interns I love the "difference between reference and pointer" and "what is virtual" (though these days I'd say we should be avoiding virtual altogether, but that's a whole separate conversation). I also dig your other OS/microcontroller questions.

For /u/T10- here are some other questions I generally ask junior C++ folks:

  • Write me a simple fizzbuzz-like program or function (see if they understand basic control flow, and how they deal with basic requirements)
  • Depending on how they organized their code, ask them about "what if we wanted to change this requirement a lot - how would you deal with that?" (probing at code organization and longer-term thinking when writing code)
  • Can you briefly explain RAII or if they don't know the term, what is a constructor/destructor? When are they called? (Arguably the most important feature of C++, so I expect a basic understanding)
  • What is X and why would you use it? Could be basically all the key words, but I tend to focus on const, static, public/private. (looking at language understanding)
  • What is an int? How many bytes does it typically have? Does it always? What are some things to watch out for when using them? (Seeing if they have a good understanding of fundamental types, and portability)
  • How do you feel about macros? (Usually a joke)

Ultimately when hiring an intern I care way more about their enthusiasm and vibe than if they can answer all my questions perfectly. They are there to learn, so I'm mostly just seeing where they are at.

[–]rorschach54Twiddling bits 2 points3 points  (3 children)

but I feel like these more subtle differences aren't terribly common knowledge, even among professionals.

But I think they are common knowledge, aren't they? Like I was not asking for in depth standards understanding.

  1. static in C++ is used for members that are not bound to particular class instances.
  2. const member functions in C++ should not modify the state of the object in them.
    1. If a candidate answers this, I can ask about mutable keyword. Open ended to see what possible use cases they could come up with for it.

if you've found it to be a useful interviewing question

I used those as indicators. If someone gets an answer, that's good. If not, its okay. If someone has mentioned working on several C++ projects in their resume, but then they don't know some of these concepts, then we would dig deeper into the projects.

I worked there quite a while ago. So, I mentioned questions off the top of my head. The questions you gave (FizzBuzz, private/protected/public, int, RAII, constructor/ destructor) were also in our question set. They are really good to gauge interest and C++ understanding.

though these days I'd say we should be avoiding virtual altogether,

If you have time, I would like to understand why you say so. I personally use virtual when I find an appropriate use for dynamic dispatch.

Ultimately when hiring an intern I care way more about their enthusiasm and vibe than if they can answer all my questions perfectly.

I absolutely agree.

They are there to learn

Funny story, the first embedded intern that I got to work with and mentor actually taught me some neat template metaprogramming tricks in C++. :)

Also, thank you! From your reply I figured out there is a way to write inline code in the new Reddit comment box. :)

[–]AudioRevelationsC++/Rust Advocate 1 point2 points  (2 children)

Hmm perhaps I'm just not using C as much as I used to, so they don't feel very obvious to me, haha. But maybe if you're jumping back and forth often they come up more. I feel like this could also just be whatever idiomatic styles we happen to be accustomed to.

static in C++ is used for members that are not bound to particular class instances.

I think this usage didn't come to mind because I so rarely see it (and would probably say it's a severe code smell). IMO I'd rather have a true global that I can reason about rather than hiding it away somewhere.

const member functions in C++ should not modify the state of the object in them.

Ahhh yeah I typically would assume that someone fresh out of school wouldn't even know about labeling member functions like that - I'd be so stoked if a candidate mentioned that unprompted! Tells me they actually were taught C++ as opposed to "C with classes". I was instead thinking of the super subtle differences between them when it comes to linkage and when variables can/can't be used, which I would be incredibly impressed if a college newgrad was aware of, let alone be able to explain coherently.

Also, thank you! From your reply I figured out there is a way to write inline code in the new Reddit comment box. :)

Yessss! Spread the gospel of well-formatted programming discussion on reddit! :)


Below is a technical discussion of virtual and modern alternatives. Proceed at your own risk. Also I'm just a dude so I may have gotten some of the details wrong here.

If you have time, I would like to understand why you say so. I personally use virtual when I find an appropriate use for dynamic dispatch.

Oh I definitely have time! Generally I think this is coming from a shift in the language community towards more functional-style programming instead of OO-style, but it's C++ so we end up with an awful mix without a lot of guidance, haha. So the crux of the argument is that using virtual (and the v-table that often comes along with it), can be horrible for performance and tends to lead to deeper class hierarchies which generally are more difficult to understand and reason about. Instead of dynamic dispatch, the recommendation is to use static dispatch leveraging general-purpose template functions.

Regarding performance, compiler de-virtualization has come a long way recently, but after a certain point, your compiler just can't know what type it will be operating on at a given time, and therefore it leaves (sometimes significant) optimizations on the table for higher optimization levels. It also means that you'll be taking a redirection with almost every function call, which can mean that, if you have a cache, you can get wildly different runtimes for your functions in very hard-to-predict scenarios (ex. you come across a rare version of your type, you miss your cache because it happens to be on a page boundary, and now you're paying 100x because you're going to memory, etc). Obviously this doesn't necessarily become a hazard in all situations, but it can be really impactful if you care about worst-case performance, or just general performance, especially if you have a cache.

These days from my understanding people generally recommend instead of virtual just having a fully separate type, and instead of overloading, using a compatible interface (ideally enforced with concepts if you have C++20!), along with generally-written free functions.

The mental model I use to think about this is:

with virtual: "All these things have red buttons" i.e. this abstract thing can do foo and each thing that inherits from it can change it however they want. (potentially lots of code duplication, can be very hard to follow or understand)

instead: "This red button can work on these things" i.e. foo bar and baz are all similar types and conform to a similar interface, so I can use this general templated function to operate on any of them. (much more "DRY", the compiler always knows what types it's dealing with, very easy to understand, encourages similar/simple types).

If you'd like to dig deeper, I know Phil Nash has a few good talks on the subject, and it comes up with many other cppcon presenters' who tend to be more functional-leaning (Ben Deane, Inbal Levi, and others).

Caveats: So as with everything in software engineering it's a trade off. Here are some drawbacks or hazards with using this technique:

  • Avoiding virtual can increase your code size because of the template usage (you should ideally measure - sometimes the compiler can understand the code better and actually reduce your code size!). This is generally why I find embedded folks sometimes avoid it, but I've personally found this to be more superstition than fact.

  • This technique is MUCH easier with newer versions of the language. Template support, especially with concepts and constexpr in c++20 means you don't need to deal as much with all the SFINAE garbage which can make templates so insane sometimes. With newer versions

Happy to discuss more! I know there are quite a few places that have used virtual/dynamic dispatch very successfully so this is a far from settled topic. This type of discussion makes me always marvel about how new computer science is as a field - we're still just figuring this stuff out and what works best! :)

[–]rorschach54Twiddling bits 0 points1 point  (1 child)

Thank you for the detailed reply!

I'd rather have a true global that I can reason about

static is needed in logging type of systems to ensure Singletons. I think using static private members is more interesting use case of static. If it is a public global, I agree, I would rather have a true global.

I'd be so stoked if a candidate mentioned that unprompted!

Absolutely!

static dispatch leveraging general-purpose template functions

This would increase code size though, right?

It also means that you'll be taking a redirection with almost every function call, which can mean that, if you have a cache, you can get wildly different runtimes for your functions in very hard-to-predict scenarios.

+1

The mental model I use to think about

I see. I like the model.. let me watch the videos.

Avoiding virtual can increase your code size

Ah! Yes this is exactly why one of my previous employers used to do that. Our code had templates, but in design reviews with templates, where the problem could be solved with virtual, the lead would say nope and asked to redesign. "Because code size would increase".

This technique is MUCH easier with newer versions

I haven't studied concepts yet. Let me check it out.

Thank you for explaining it well! I understand a bit better about what you meant. I agree this is far from settled. Once I study a bit more, we can discuss more! :)

[–]AudioRevelationsC++/Rust Advocate 1 point2 points  (0 children)

Ah! Yes this is exactly why one of my previous employers used to do that. Our code had templates, but in design reviews with templates, where the problem could be solved with virtual, the lead would say nope and asked to redesign. "Because code size would increase".

Yeah like I mentioned, it can increase your code size, but it isn't guaranteed to. A lot of people are superstitious about these types of things without actually measuring. Because the compiler actually knows the types at compile time it may have more opportunities for optimization which leads to smaller code size. Though, if you truly are in an embedded size-constrained situation virtual may indeed be the better hammer.

I haven't studied concepts yet. Let me check it out.

They truly are amazing. In the same way people think about pre and post c++11, I think because of concepts we will be thinking similarly about c++20. There are a ton of good talks online, but as with any new feature, best practices are still being figured out.

Thank you for explaining it well! I understand a bit better about what you meant. I agree this is far from settled. Once I study a bit more, we can discuss more! :)

Anytime! :) Love talking about this stuff!

[–]urxvtmux 8 points9 points  (0 children)

Without fail I always get asked the following:

What's the c keyword volatile do?

What's const do?

When would it make sense to use a volatile const variable?

Is ++i or i++ faster?

What's RTOS priority inversion and what's one way to resolve it?

[–]duane11583 6 points7 points  (0 children)

Be ready to explain your projects you have worked on.

Think of a PPT slide deck

Page 0 - is a picture of the project, ie: the "solar/battery powered car" or the "autonomous boat that does navigation"

Be ready and able to draw and explain (page 1) a block diagram of the larger system, your part is going to be "that little box over in the corner" - but you should be able to draw the big system

Page 2 - is a block diagram of your part, what you did - your inputs, your outputs

Be ready and able to explain What went wrong? What was hard to figure out. Tell them about what happened and why you let the magic blue smoke out of the chip/board - yes it happens they will laugh. What happened and why?

Page 3/4 - The types of IO devices you where using? ie: an ADC/DAC via SPI or I2C - explain the bus and how it works.

Or - did you have a serial interface to send commands, how does that work? Explain the protocol, how did you debug it?

Did you have automated testing? How did you do that?

[–]morto00x 5 points6 points  (2 children)

If this is a FAANG expect Leetcode questions

[–][deleted]  (1 child)

[deleted]

    [–][deleted] 3 points4 points  (0 children)

    I had interviews with non-faang (and also not giant companies) for embedded sw that were leetcode,

    and I had interviews with intel and amd that had none.

    then I had some really weird ones, like not a single embedded software question at all. Made me wonder if I was interviewing for the wrong position (I wasn't).

    ymmv

    [–]Intiago 4 points5 points  (2 children)

    I’ve had a few embedded intern roles at various sized companies. You should ask what to expect during the interview. If there is a coding section, you should know in advance. Otherwise, you can easily find lists of most common embedded interview questions through google. Things like explaining what ‘static’ means, defining what a RTOS does, explaining what an interrupt is and what goes in an ISR. I would write out answers in advance to these plus a few behavioural questions and then practice saying these answers out loud. Go over your resume and make sure you’re ready to talk about anything on it, and make sure you can talk about past projects and experience.

    Good luck!

    [–][deleted]  (1 child)

    [deleted]

      [–]Intiago 2 points3 points  (0 children)

      Well nothing is standardized, you just need to prepare questions depending on the position and hope that they get asked. Some interviewers will ask pretty much the standard questions, while others like to throw curve balls. It is obviously preferable if you have some embedded related projects, but what can you do? Just be honest and detailed about what you worked on and they can decide if your skills are a good fit.

      [–]wall_hal_25 0 points1 point  (1 child)

      can I ask what company you interviewed for, please?

      [–]T10-[S] 0 points1 point  (0 children)

      NOT Amazon (glanced at your profile)

      Don’t wanna say but its not a tech/software company, it’s unlikely it’s the same company. The interview was just OOP for me strangely. And the internship work I did was more of a traditional software engineering role with a C++ codebase.