Hi,
My question certainly stems from the imposter syndrome that I am living right now for no good reason, but when looking to resolve some issues for embedded C problems, I come across a lot of post from people that have a deep understanding of the language and how a mcu works at machine code level.
When I read these posts, I do understand what the author is saying, but it really makes me feel like I should know more about what’s happening under the hood.
So my question is this : how do you rate yourself in your most used language? Do you understand the subtilities and the nuance of your language?
I know this doesn’t necessarily makes me a bad firmware dev, but damn does it makes me feel like it when I read these posts.
I get that this is a subjective question without any good responses, but I’d be interested in hearing about different experiences in the hope of reducing my imposter syndrome.
Thanks
I’ve been using c# since .net 2 which came out around the turn of the century (lol)
I’d happily call myself an expert. I can do anything I need to and easily dive into the standard library source code or even IL when needed.
But even then there are topics I could easily learn more on particularly the very performance focused struct features and intrinsics.
I’ve found LLMs to be super useful when you have a very specific question about a feature. I use bing ai at work so it sources all its answers and you can dive into the articles for more detail.
Programming is a never ending learning journey and you just have to keep going. When you get something you don’t fully understand to a deep dive there are always resources for everything.
novice still learning everyday
I don’t think your question relates to the language as much as to the platform. The language of choice is somewhat irrelevant and what you care about is what actually happens under the hood.
For the likes of java and go you want to have some understanding of what runtime does for the memory allocations and how their GCs work. For python you sometimes end up in the spots where you need to understand what limitations the GIL imposes (even more important now that they are trying to get rid of it). When you run C (or C++ or Rust) on the embedded hardware it really helps to understand what exactly bit flipping does in specific registers and what DMA means for how you write your code.
You don’t really have to know it all. You can absolutely write code without caring about anything of that and I know plenty software engineers that do. Some people write amazing functional things in java without ever questioning what it does to the machines and what resources you need to run it.
If you start questioning it, that will only expand your understanding. It’s not a lateral move from e.g. C to Rust where you need to learn a lot to write your code in a memory-safe way, it’s a movement deeper into the stack and what you learn there will be applicable to any language you use for this stack.
Answering your question: I always feel bad about not understanding some low-level concept. I have stacks of MCU reference docs lying around, printed, highlighted; I have archives with sample code, and hand-annotated CMSIS reversing notes. Embedded world is hard because you can’t just know C and be done with it. You have to know the hardware, too.
Here’s my advice for you. Make notes of things that you learn from people smarter than you. Create a web of those notes and see where your gaps are. Then, work on learning something in those gaps in particular and see if you can make a blog post or something of your own. When you share what you learn you become one of those people with deep understanding that others look up to. There’s always someone struggling with something that you either know or know how to figure it out.
What I like about embedded is that it’s between software and hardware, where you have to know both to a certain extent. It kinda feels like being a mad scientist bringing a monster to life. Seeing that my code makes physical actions (lighting a LED or controlling a motor) never seems to get old, even when trivial.
I am confronted everyday about the things I don’t know because I work in a startup and I am the only one that does what I do. Any issue that I have tells me what I need to learn to fix the issue.
You are right that for a lot of people, what I do seems like magic and we often forget the extent of our knowledge because it has become innate.
Thanks for the insight, I appreciate it.
I’d say average.
In every project and in every team, I end up being strong because I fix the hard stuff. I debug better and I deliver mostly bug free code. My code is more efficient and performant than my coworkers most of the time.
That’s gotta count for something.
Imposter syndrome is good for me. Keeps me learning.
After 6 years of seriously using Python regularly, I’d probably give myself a 6/10. I feel comfortable with best practices and making informed design decisions. I have no problem using linting and testing tools. And I’ve contributed to large open source projects. I could improve a lot by learning more about the standard library and some core computer science concepts that inform the design of the language. I’m pretty weak in web frameworks too, unfortunately.
After 3-4 years of using python I’m bumping you up to a 7 so I can fit in at a 5. Congrats on your upgrade. I’ve never contributed to open source but I’ve fixed issues in publocly archived tools so that they aren’t buggy for my team. I can see errors and know what likely caused them and my code literacy is decent. That being said, I think I’m far from advanced.
After almost 12~15 years of programming in C and C++, I would give myself a solid “still don’t know enough” out of 10.
After almost 12~15 years of programming in C and C++, I would give myself a solid “still don’t know enough” out of 10.
That resonates so thoroughly.
And while it can 100% also be the case in any tool or language, it’s somehow 300% true for C and C++.
how do you rate yourself in your most used language?
I know things that no human should have to carry the knowledge of
Do you understand the subtilities and the nuance of your language?
My soul is scarred by the nuanced minutia of many an RFC.
in the hope of reducing my imposter syndrome.
There’s but two types in software - those who have lived to see too much…and those who haven’t…yet.
If you step in enough shit you eventually learn to realise when you are about to step in it again. I think the most knowledgeable people are those that have failed the most and found something helpful along the way, seems you are well on your journey so just keep steeping. At some point the abstractions you have control over become unreliable until you understand how they interact with lower level systems and the balance of control comes back because you know know the circumstances in which these abstractions work in your favour.
The more I learn about my language the less I think it matters. Maybe in embedded C you can’t just leave everything to the compiler though.
Not every thing, but still most things by far.
It’s a strong typed language with a minimal set of guard rails, so there is certainly some considerations to take into account, but the compiler are pretty good and give more leeway to the dev.
A one out of ten. I consider myself the world’s second worst programmer.
Who is the first?
Odds are the worst one is still using Twitter.
The guy who was using my name to make code submissions 2-3 years prior.
You mean the worst? I don’t know. I’m just hopeful that I’m not actually the worst. Fingers crossed.
Imposter syndrome is strong
By any chance, do you use a niche language that has only two programmers?
Nope. I’m just that bad. I feel like I have a logical mind but it just seems like the command don’t do what I think they will, won’t operate on a certain type of variable or Holy crap I forgot a friggin space or semi-colon or something.
Languages in order of proficiency: C++ HTML/CSS Matlab Basic Fortran (1 class taken)
But when I say proficient I seriously mean looking stuff up on the internet for every single line. And I haven’t used Basic in decades.
I’ve learned a lot by breaking things. By making mistakes and watching other people make mistakes. I’ve writing some blog posts that make me look real smart.
But mostly just bang code together until it works. Run tests and perf stuff until it looks good. It’s time. I have the time to write it up. And check back on what was really happening.
But I still mostly learn by suffering.
But I still mostly learn by suffering.
That resonates so much. Almost every time someone is deeply impressed with something I know, it brings back a painful memory of how I learned it.
I really like brain twisters. It can get frustrating at times, but it’s the most fun out of the profession to me.
I’ve been using Scala professionally for 3 years. I don’t know what I’m doing most of the time because we have a ton of implicites and monads and extension methods. I just know the general idea and can get where I want by reading types.
I’ve been creating a language for fun for nearly 6 years. I often don’t know what’s going on under the hood because it’s somewhat complex. I think this is normal for every language. You don’t have to know everything to be able to use it. You don’t have to write blog posts once a week about the language subtleties you found.
The blogposts are the example I had because this is usually where I find my solutions.
I do understand that I don’t need an in depth knowledge of everything about my language, but I sometime feel like I should know more. But again, this is the imposter syndrome talking.
I am thinking about blogging once my kids are older and I have more time because I am grateful when someone else does and I want to contribute as well.
Better than many, mediocre.
With my coworkers I’ve got a strange ability to pick up any language that tastes like c, and get stuff done. I’m sure I’ve confused our c# guys when I make a change to their code and ask for a code review, because I’ll chase down quality of life improvements for myself. (Generally, I will make the change and ask if I have any unintended side effects, because in an MCU, I know what all my side effects are, multi threaded application?, not at all)
Edit: coming from a firmware view, I’ve made enough mistakes to realize when order of operations will stab me, when a branch is bad because that pipeline hit will hurt, and I still get & vs && wrong more often than I would like to admit.
I just have to say “tastes like c” is a visceral way to say it. I approve.
I think I’ll never not make & &&, | || or = == operators mistakes. It’s so easy to go over it fast and not notice the mistakes.
I like developing MCU firmwares because there is limited amout of resources and you usually have direct control of what is running when.
I feel the better than many, but mediocre in my soul. I mean, I get paid to code, so I certainly have a good enough knowledge to do so. But I have the tendancy to undersell myself.
What helped me a lot with pushing deeper down into the language innards is to have people to explain things to.
Last week, for example, one of our students asked what closures are.
Explaining that was no problem, I was also able to differentiate them from function pointers, but then she asked what in Rust the traits/interfacesFn
,FnMut
andFnOnce
did (which are implemented by different closures).And yep, she struck right into a blank spot of my knowledge with that.
I have enough of an idea of them to just fill in something and let the compiler tell me off when I did it wrong.
Even when designing an API, I’ve worked out that you should start with anFnOnce
and only progress toFnMut
, thenFn
and then a function pointer, as the compiler shouts at you (basically they’re more specific and more restrictive for what the implementer of the closure is allowed to do).But yeah, these rules of thumb just don’t suffice for an actual explanation.
I couldn’t tell you why these different traits are necessary or what the precise differences are.
So, we’ve been learning about them together and I have a much better understanding now.Even in terms of closures in general (independent of the language), where I thought I had a pretty good idea, I had the epiphany that closures have two ways of providing parameters, one for the implementer (captured out of the context) and one for the caller (parameter list).
Obviously, I was aware of that on some level, as I had been using it plenty times, but I never had as clear of an idea of it before.I work in a small start-up where I am the only one doing what I do, so my epiphanies come from the struggles I have.
Other people I work with often have a blank look in their eyes when I try to explain some issues or what the code does because they don’t have the skillset to comprehend what I am doing. So this isn’t a path for me (yet, hopefully we can grow enough where we need more people in my field).
But I appreciate your experience. I will certainly think about a way to play in the innards of my language so that I can understand it better.
1/10 in python. I took a college course or two and enjoyed it.